/* Shoora — dark, techy, cheerful. Live speech, on every phone.
   Committed dark theme, vibrant multi-hue accents, glassy surfaces,
   smart-but-subtle motion. Accessibility-first: high contrast, visible
   focus, reduced-motion aware (this is an accessibility company). */
:root {
  color-scheme: dark;
  --bg: #070b16;
  --bg-2: #0b1226;
  --surface: rgba(255, 255, 255, 0.045);
  --surface-solid: #101a33;
  --line: rgba(255, 255, 255, 0.10);
  --ink: #eaf1ff;
  --ink-2: #9fb2d8;
  --cyan: #22d3ee;
  --teal: #2dd4bf;
  --violet: #a78bfa;
  --pink: #fb7185;
  --amber: #fbbf24;
  --brand: #38dcff;
  --ring: #67e8f9;
  --grad: linear-gradient(120deg, #22d3ee, #a78bfa 55%, #fb7185);
  --grad-warm: linear-gradient(120deg, #2dd4bf, #fbbf24);
  --radius: 18px;
  --shadow: 0 18px 50px rgba(0, 0, 0, 0.45);
  --glow: 0 0 0 1px rgba(56, 220, 255, 0.14), 0 12px 40px rgba(56, 220, 255, 0.10);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  color: var(--ink);
  background: var(--bg);
  line-height: 1.6;
  font-size: 18px;
  /* clip, not hidden: hidden makes <body> a scroll container and silently breaks
     position:sticky (e.g. the reader's floating menu bar) on mobile. clip stops
     horizontal scroll without establishing a scroll container. */
  overflow-x: clip;
}
/* animated aurora backdrop */
body::before {
  content: "";
  position: fixed; inset: -20% -10% auto -10%; height: 90vh; z-index: -2;
  background:
    radial-gradient(40% 55% at 18% 20%, rgba(34, 211, 238, 0.20), transparent 60%),
    radial-gradient(38% 50% at 82% 12%, rgba(167, 139, 250, 0.20), transparent 60%),
    radial-gradient(45% 55% at 60% 45%, rgba(251, 113, 133, 0.14), transparent 60%);
  filter: blur(10px);
  animation: drift 22s ease-in-out infinite alternate;
}
body::after { content: ""; position: fixed; inset: 0; z-index: -1; background: radial-gradient(120% 80% at 50% -10%, transparent 55%, var(--bg) 100%); pointer-events: none; }
@keyframes drift { 0% { transform: translate3d(0,0,0) scale(1); } 100% { transform: translate3d(0,-4%,0) scale(1.08); } }

h1, h2, h3 { line-height: 1.12; color: var(--ink); font-weight: 800; letter-spacing: -0.02em; }
h1 { font-size: clamp(2.3rem, 5.5vw, 3.8rem); margin: 0 0 0.6rem; }
h2 { font-size: clamp(1.6rem, 3.6vw, 2.4rem); margin: 0 0 0.8rem; }
h3 { font-size: 1.2rem; margin: 0 0 0.4rem; color: var(--ink); }
p { margin: 0 0 1rem; color: var(--ink-2); }
a { color: var(--brand); }
:focus-visible { outline: 3px solid var(--ring); outline-offset: 3px; border-radius: 6px; }

.grad-text { background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; background-size: 200% auto; animation: shimmer 8s linear infinite; }
@keyframes shimmer { to { background-position: 200% center; } }

.wrap { max-width: 1120px; margin-inline: auto; padding-inline: clamp(1rem, 4vw, 2rem); }
.skip { position: absolute; left: -999px; top: 0; background: var(--brand); color: #05202a; font-weight: 700; padding: 0.6rem 1rem; z-index: 100; border-radius: 0 0 10px 0; }
.skip:focus { left: 0; }
/* Only surface it for keyboard users — not after a touch/click navigation (mobile). */
.skip:focus:not(:focus-visible) { left: -999px; }

/* header */
header.site { position: sticky; top: 0; z-index: 40; background: rgba(7, 11, 22, 0.72); backdrop-filter: blur(14px); border-bottom: 1px solid var(--line); }
header.site .bar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding-block: 0.85rem; }
.brand { display: inline-flex; align-items: center; gap: 0.6rem; text-decoration: none; color: var(--ink); font-weight: 800; font-size: 1.4rem; letter-spacing: -0.03em; }
.brand .dot { inline-size: 12px; block-size: 12px; border-radius: 50%; background: var(--grad); box-shadow: 0 0 16px rgba(56, 220, 255, 0.8); animation: pulse 2.6s ease-in-out infinite; }
@keyframes pulse { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.35); opacity: 0.75; } }
nav.main { display: flex; gap: 0.3rem; align-items: center; flex-wrap: wrap; }
nav.main a { color: var(--ink-2); text-decoration: none; font-weight: 600; padding: 0.5rem 0.8rem; border-radius: 10px; transition: color .2s, background .2s; }
nav.main a[aria-current="page"] { color: var(--ink); background: var(--surface); }
nav.main a:hover { color: var(--ink); background: var(--surface); }

/* nav dropdown (e.g. Documents under About) */
.navdrop { position: relative; }
.navcaret { font-size: 0.7rem; opacity: 0.7; }
.navdrop-menu {
  position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: 0; z-index: 50;
  min-inline-size: 160px; display: grid; gap: 2px; padding: 6px;
  background: var(--surface-solid); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow);
  opacity: 0; visibility: hidden; transform: translateY(-4px); transition: opacity .15s, transform .15s, visibility .15s;
}
.navdrop:hover .navdrop-menu, .navdrop:focus-within .navdrop-menu { opacity: 1; visibility: visible; transform: none; }
.navdrop-menu a { display: block; white-space: nowrap; }

/* buttons */
.btn { display: inline-flex; align-items: center; gap: 0.5rem; font: inherit; font-weight: 700; padding: 0.85rem 1.5rem; border-radius: 999px; border: 1px solid transparent; text-decoration: none; cursor: pointer; transition: transform .18s ease, box-shadow .25s ease, filter .2s; }
.btn[hidden] { display: none; }
.btn:active { transform: translateY(1px); }
.btn-primary { background: linear-gradient(120deg, #0891b2, #7c3aed 55%, #db2777); color: #ffffff; font-weight: 800; text-shadow: 0 1px 2px rgba(0,0,0,0.28); box-shadow: 0 10px 30px rgba(124, 58, 237, 0.28); background-size: 160% auto; }
.btn-primary:hover { filter: brightness(1.08); box-shadow: 0 14px 40px rgba(219, 39, 119, 0.38); transform: translateY(-2px); }

/* monochrome, distinct caption-bubble logo mark */
.logo-mark { display: block; color: var(--ink); flex: 0 0 auto; }
.brand:hover .logo-mark { color: var(--brand); }

/* language switcher (flag icons) */
.langswitch { display: inline-flex; gap: 2px; padding: 3px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); }
.langswitch .lang { display: grid; place-items: center; inline-size: 30px; block-size: 26px; border-radius: 999px; text-decoration: none; font-size: 1.05rem; line-height: 1; filter: grayscale(0.5) opacity(0.65); transition: filter .2s, background .2s; }
.langswitch .lang:hover { filter: none; background: rgba(255,255,255,0.06); }
.langswitch .lang.on { filter: none; background: rgba(255,255,255,0.10); box-shadow: inset 0 0 0 1px var(--line); }

/* demo language toggle (text buttons in a switch) */
#demoLang .lang { inline-size: auto; padding-inline: 0.6rem; font-size: 0.85rem; font-weight: 700; color: var(--ink-2); border: none; background: transparent; cursor: pointer; }
#demoLang .lang.on { color: var(--ink); }

/* icon button (sign in) */
.iconbtn { display: grid; place-items: center; inline-size: 36px; block-size: 36px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); text-decoration: none; transition: color .2s, border-color .2s; }
.iconbtn:hover { color: var(--ink); border-color: var(--brand); box-shadow: var(--glow); }
.btn-ghost { background: var(--surface); color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--brand); box-shadow: var(--glow); }

/* sections */
section { padding-block: clamp(2.75rem, 6vw, 5rem); }
.eyebrow { text-transform: uppercase; letter-spacing: 0.16em; font-size: 0.78rem; font-weight: 800; color: var(--teal); margin: 0 0 0.7rem; }
.lede { font-size: clamp(1.12rem, 2.4vw, 1.4rem); color: var(--ink-2); max-width: 42ch; }

.hero { position: relative; }
.hero .grid { display: grid; grid-template-columns: 1.05fr 0.95fr; gap: clamp(1.5rem, 4vw, 3rem); align-items: center; padding-block: clamp(2rem, 6vw, 4rem); }
@media (max-width: 860px) { .hero .grid { grid-template-columns: 1fr; } }
.pill { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.35rem 0.85rem; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); font-size: 0.85rem; font-weight: 600; color: var(--ink-2); margin-bottom: 1.1rem; }
.pill .dot { inline-size: 8px; block-size: 8px; border-radius: 50%; background: var(--teal); box-shadow: 0 0 10px var(--teal); }
.cta-row { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-top: 1.5rem; }

/* glass panel + live-speech visualiser */
.panel { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: 24px; padding: clamp(1.25rem, 3vw, 1.9rem); box-shadow: var(--shadow); backdrop-filter: blur(8px); overflow: hidden; }
.panel .glow { position: absolute; inset: -1px; background: var(--grad); opacity: 0.10; z-index: -1; }
.viz { display: flex; align-items: flex-end; gap: 5px; height: 74px; margin-bottom: 1rem; }
.viz span { flex: 1; border-radius: 6px 6px 3px 3px; background: var(--grad); opacity: 0.9; animation: eq 1.1s ease-in-out infinite; }
@keyframes eq { 0%,100% { height: 22%; } 50% { height: 100%; } }
.chat { display: grid; gap: 0.55rem; }
.line { display: flex; align-items: center; gap: 0.6rem; padding: 0.6rem 0.8rem; border-radius: 12px; background: rgba(255,255,255,0.05); border: 1px solid var(--line); font-size: 0.95rem; }
.line .flag { font-size: 1.1rem; }
.line small { color: var(--ink-2); }

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.25rem; }
.card { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.6rem; box-shadow: var(--shadow); transition: transform .25s ease, border-color .25s ease, box-shadow .25s ease; overflow: hidden; }
.card:hover { transform: translateY(-4px); border-color: rgba(56,220,255,0.4); box-shadow: var(--glow); }
.card .ico { font-size: 1.9rem; line-height: 1; margin-bottom: 0.6rem; }
.card p { margin-bottom: 0; }

.soft { position: relative; }
.split { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; }
ul.checks { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.65rem; }
ul.checks li { padding-inline-start: 1.9rem; position: relative; color: var(--ink-2); }
ul.checks li::before { content: "✓"; position: absolute; inset-inline-start: 0; color: var(--teal); font-weight: 900; }

.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 1rem; }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.4rem; text-align: center; }
.stat b { display: block; font-size: 2.1rem; font-weight: 800; background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.stat span { color: var(--ink-2); font-size: 0.95rem; }

/* forms */
.form { display: grid; gap: 0.95rem; max-width: 580px; }
.form label { font-weight: 700; color: var(--ink); display: grid; gap: 0.35rem; }
.form input, .form select, .form textarea { font: inherit; padding: 0.8rem 0.9rem; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-solid); color: var(--ink); width: 100%; }
.form input::placeholder, .form textarea::placeholder { color: #64789c; }
.form input:focus, .form select:focus, .form textarea:focus { border-color: var(--brand); outline: none; box-shadow: 0 0 0 3px rgba(56,220,255,0.18); }
.form .row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.95rem; }
@media (max-width: 560px) { .form .row { grid-template-columns: 1fr; } }
.alert { background: rgba(251, 113, 133, 0.12); color: #ffb3bf; border: 1px solid rgba(251,113,133,0.4); padding: 0.7rem 1rem; border-radius: 12px; }
.muted { color: var(--ink-2); font-size: 0.95rem; }

/* footer */
footer.site { border-top: 1px solid var(--line); background: rgba(11, 18, 38, 0.6); padding-block: 2.5rem; margin-top: 3rem; }
footer.site .cols { display: flex; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; align-items: center; }
footer.site a { color: var(--brand); }

/* stats tables */
table { border-collapse: collapse; width: 100%; font-size: 0.92rem; }
th, td { text-align: start; padding: 0.55rem 0.6rem; border-bottom: 1px solid var(--line); }
th { color: var(--ink-2); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; }
.scroll { overflow-x: auto; }
.bars { display: grid; gap: 0.4rem; }
.bar { display: grid; grid-template-columns: 96px 1fr 46px; align-items: center; gap: 0.6rem; font-size: 0.85rem; color: var(--ink-2); }
.bar .track { background: var(--surface); border: 1px solid var(--line); border-radius: 6px; height: 15px; overflow: hidden; }
.bar .fill { background: var(--grad); height: 100%; border-radius: 6px; }

/* competition matrix */
.matrix th { white-space: nowrap; }
.matrix th, .matrix td { border-bottom: 1px solid var(--line); }
.matrix tr.us { background: rgba(56, 220, 255, 0.08); }
.matrix tr.us td:first-child { color: var(--brand-700); }
.mark { display: inline-grid; place-items: center; inline-size: 24px; block-size: 24px; border-radius: 50%; font-weight: 800; font-size: 0.85rem; }
.mark.yes { color: #062a20; background: var(--teal); }
.mark.no { color: var(--ink-2); background: var(--surface); border: 1px solid var(--line); }

/* reader dim / dark mode — pure-black background + dimmed text for dark venues */
html.dim, html.dim body { background: #000 !important; }
html.dim body::before, html.dim body::after { display: none !important; }
html.dim .panel, html.dim #captions { background: #050505 !important; border-color: #1a1a1a !important; box-shadow: none !important; }
html.dim .cap-line { background: #0a0a0a !important; border-color: #1a1a1a !important; color: #8f8f8f !important; }
html.dim .cap-partial { color: #6f6f6f !important; }
html.dim .cap-line span { color: #7a7a7a !important; }
html.dim header.site, html.dim footer.site { background: #000 !important; border-color: #141414 !important; }
html.dim .muted, html.dim .eyebrow, html.dim h1, html.dim .lede { color: #6a6a6a !important; }

/* live-narration demo captions */
.cap-line { padding: 0.5rem 0.8rem; background: rgba(255,255,255,0.05); border: 1px solid var(--line); border-radius: 10px; font-size: 1.05em; color: var(--ink); animation: capin 0.3s ease; }
.cap-partial { padding: 0.2rem 0.8rem; color: var(--teal); font-size: 1.15em; min-block-size: 1.4em; }
.btn.rec { background: linear-gradient(120deg, #fb7185, #e11d48); }
@keyframes capin { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* rotating stories */
#storyRotator .story-item { grid-area: 1 / 1; opacity: 0; visibility: hidden; transition: opacity .6s ease; max-inline-size: 68ch; }
#storyRotator .story-item.on { opacity: 1; visibility: visible; }
.story-dot { inline-size: 9px; block-size: 9px; border-radius: 50%; background: var(--line); border: none; padding: 0; cursor: pointer; transition: background .2s, transform .2s; }
.story-dot.on { background: var(--brand); transform: scale(1.25); }

/* scroll reveal */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity .7s ease, transform .7s ease; }
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .reveal { opacity: 1; transform: none; }
}

/* Dry / Live admin toggle on the narration screen */
.btn.bc-toggle{ background:var(--surface-solid); border:1px solid var(--line); color:var(--ink); }
.btn.bc-toggle.on{ background:#fb7185; border-color:#fb7185; color:#0b0f14; font-weight:800; }

/* Mobile navigation — hamburger + slide-down panel */
.nav-toggle { display: none; }
@media (max-width: 900px) {
  header.site .bar { position: relative; }
  .nav-toggle {
    display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
    inline-size: 44px; block-size: 40px; padding: 10px 11px; margin-inline-start: auto;
    background: var(--surface); border: 1px solid var(--line); border-radius: 12px; cursor: pointer;
  }
  .nav-toggle span { display: block; height: 2px; width: 100%; background: var(--ink); border-radius: 2px; transition: transform .25s ease, opacity .2s ease; }
  .nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  nav.main {
    display: none; position: absolute; inset-inline: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: .1rem; flex-wrap: nowrap;
    background: rgba(7, 11, 22, 0.98); backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line); box-shadow: 0 18px 40px rgba(0,0,0,.45);
    padding: .6rem 1rem 1.1rem; max-height: calc(100vh - 64px); overflow-y: auto;
  }
  nav.main.open { display: flex; }
  nav.main a { padding: .7rem .8rem; border-radius: 10px; }
  nav.main > .btn { justify-self: stretch; text-align: center; margin-top: .35rem; }

  /* dropdowns expand inline (no hover on touch) */
  .navdrop { position: static; }
  .navdrop-menu {
    position: static; opacity: 1; visibility: visible; transform: none;
    box-shadow: none; border: none; background: transparent; padding: 0 0 .2rem .9rem; min-inline-size: 0;
  }
  .navdrop-toggle .navcaret { display: none; }
  .langswitch { align-self: flex-start; margin-top: .5rem; }
}

/* Audience Q&A cards (reader ask box, speaker answers, admin view) */
.qcard { border: 1px solid var(--line); border-radius: 12px; padding: .6rem .7rem; background: var(--surface-solid); }
.qcard.blocked { opacity: .5; }
.qrow { color: var(--ink); font-size: .92rem; line-height: 1.45; }
.qtag { display: inline-grid; place-items: center; inline-size: 20px; block-size: 20px; border-radius: 6px; font-size: .72rem; font-weight: 800; vertical-align: middle; }
.qtag.q { background: rgba(56, 220, 255, .16); color: var(--brand); }
.qtag.a { background: rgba(52, 211, 153, .18); color: #34d399; }
.arow { color: var(--ink-2); font-size: .9rem; margin-top: .4rem; padding-inline-start: .2rem; }
.qtools { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .55rem; }
.qtools .qAnsInput { flex: 1 1 140px; padding: .5rem .65rem; border: 1px solid var(--line); border-radius: 9px; background: var(--bg); color: var(--ink); font: inherit; }
.qtools .btn { padding: .45rem .8rem; font-size: .82rem; }

/* AI cleanup: brief highlight when a caption line is refined in place */
@keyframes capfix { 0% { background: rgba(56,220,255,.20); } 100% { background: transparent; } }
.cap-line.cap-fixed { animation: capfix .9s ease; border-radius: 6px; }
@media (prefers-reduced-motion: reduce) { .cap-line.cap-fixed { animation: none; } }

/* Per-line timestamp on the viewer page */
.cap-time { font-size: .62rem; color: var(--ink-2); opacity: .55; margin-inline-start: .5rem; white-space: nowrap; vertical-align: baseline; }

/* User dropdown: logout button styled as a menu item */
.navdrop-menu .navdrop-logout { display:block; width:100%; text-align:start; background:none; border:none; color:var(--ink-2); font:inherit; font-weight:600; padding:.5rem .8rem; border-radius:10px; cursor:pointer; }
.navdrop-menu .navdrop-logout:hover { color:var(--ink); background:var(--surface); }

/* Sign language fingerspelling (ASL manual alphabet, local images) */
.sign-letter { width: 34px; height: auto; background: #fff; border-radius: 6px; padding: 2px; box-shadow: 0 1px 3px rgba(0,0,0,.2); }
.sign-space { display: inline-block; width: 14px; }

/* Narration comments (reader) */
.cap-cmt{ margin-inline-start:.5rem; padding:0 .25rem; border:0; background:transparent; cursor:pointer; font-size:.72rem; line-height:1; opacity:.45; vertical-align:middle; border-radius:6px }
.cap-cmt:hover{ opacity:1; background:var(--surface) }
.cmt-inline{ display:flex; gap:.4rem; align-items:flex-start; margin:.35rem 0 .5rem; padding-inline-start:.6rem }
.cmt-inline textarea{ flex:1; padding:.45rem .6rem; border:1px solid var(--line); border-radius:9px; background:var(--surface-solid); color:var(--ink); font:inherit; font-size:.9rem; resize:vertical }
.cmt-inline a{ font-size:.85rem }
.cmt-card{ position:relative; border:1px solid var(--line); border-radius:12px; padding:.6rem .8rem; background:var(--surface) }
.cmt-quote{ font-size:.82rem; color:var(--ink-2); font-style:italic; border-inline-start:3px solid var(--brand); padding-inline-start:.55rem; margin-bottom:.35rem; opacity:.85 }
.cmt-body{ color:var(--ink); font-size:.95rem; white-space:pre-wrap; padding-inline-end:3.5rem }
.cmt-del{ position:absolute; inset-block-start:.5rem; inset-inline-end:.6rem; border:0; background:transparent; color:var(--ink-2); cursor:pointer; font-size:.78rem; opacity:.6 }
.cmt-del:hover{ opacity:1; color:var(--pink) }

/* Saved-session relationship tags */
.saved-tag{ display:inline-block; font-size:.68rem; font-weight:700; text-transform:uppercase; letter-spacing:.03em; padding:.12rem .5rem; border-radius:999px; margin-inline-start:.4rem; vertical-align:middle; border:1px solid var(--line) }
.saved-tag.owner{ color:#065f46; background:rgba(45,212,191,.16); border-color:rgba(45,212,191,.4) }
.saved-tag.guest{ color:#7c3aed; background:rgba(167,139,250,.16); border-color:rgba(167,139,250,.4) }
.saved-tag.demo{ color:var(--ink-2); background:var(--surface) }

/* Hero animated stage scene: speaker → live captions on audience phones */
.stage-scene{ display:block; width:100%; height:auto; margin-bottom:1rem; color:var(--ink);
  filter:drop-shadow(0 10px 30px rgba(56,220,255,.10)) }
.ss-speaker{ transform-box:fill-box; transform-origin:center bottom; animation:ssBob 3.2s ease-in-out infinite }
.ss-wave{ transform-box:fill-box; transform-origin:left center; opacity:0;
  animation:ssWave 1.6s ease-out infinite; animation-delay:var(--d) }
.ss-head{ transform-box:fill-box; transform-origin:center bottom; animation:ssNod 3s ease-in-out infinite; animation-delay:var(--d) }
.ss-phone{ transform-box:fill-box; transform-origin:center; animation:ssFloat 4s ease-in-out infinite }
.ss-lines rect{ transform-box:fill-box; transform-origin:left center; width:var(--w);
  transform:scaleX(0); animation:ssType 6s cubic-bezier(.2,.7,.3,1) infinite; animation-delay:var(--d) }
.ss-caret{ animation:ssBlink 1s step-end infinite }
@keyframes ssBob{ 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(-2.5px) } }
@keyframes ssWave{ 0%{ opacity:0; transform:translateX(0) scale(.6) } 25%{ opacity:.9 }
  100%{ opacity:0; transform:translateX(14px) scale(1.25) } }
@keyframes ssNod{ 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(-1.5px) } }
@keyframes ssFloat{ 0%,100%{ transform:translateY(0) rotate(0deg) } 50%{ transform:translateY(-4px) rotate(1.5deg) } }
/* words appear across the line, hold, then the screen resets for the next utterance */
@keyframes ssType{ 0%{ transform:scaleX(0) } 8%,78%{ transform:scaleX(1) } 90%,100%{ transform:scaleX(0) } }
@keyframes ssBlink{ 0%,55%{ opacity:1 } 56%,100%{ opacity:0 } }
@media (prefers-reduced-motion: reduce){
  .ss-speaker,.ss-wave,.ss-head,.ss-phone,.ss-lines rect,.ss-caret{ animation:none }
  .ss-lines rect{ transform:scaleX(1) }
  .ss-wave{ opacity:.6 }
}

/* Competitive analysis table */
.comp-table{ width:100%; border-collapse:separate; border-spacing:0; font-size:.92rem }
.comp-table th, .comp-table td{ padding:.7rem .85rem; text-align:start; vertical-align:top; border-bottom:1px solid var(--line) }
.comp-table thead th{ font-size:.82rem; text-transform:uppercase; letter-spacing:.03em; color:var(--ink-2); border-bottom:2px solid var(--line); white-space:nowrap }
.comp-table tbody th[scope=row]{ font-weight:700; color:var(--ink); white-space:nowrap }
.comp-table td{ color:var(--ink-2) }
.comp-table .comp-us{ background:linear-gradient(180deg, rgba(34,211,238,.10), rgba(167,139,250,.08)); color:var(--ink); font-weight:600 }
.comp-table thead th.comp-us{ color:var(--brand); font-weight:800; border-bottom-color:var(--brand) }
.comp-table tbody tr:last-child th, .comp-table tbody tr:last-child td{ border-bottom:0 }

/* Speaker page: Speaker / Listener tabs */
.spk-tabs{ display:inline-flex; gap:.3rem; margin-top:1.1rem; padding:.28rem; border:1px solid var(--line); border-radius:999px; background:var(--surface) }
.spk-tab{ border:0; background:transparent; color:var(--ink-2); font:inherit; font-size:.85rem; font-weight:700; padding:.4rem .7rem; border-radius:999px; cursor:pointer; transition:background .15s, color .15s; white-space:nowrap }
.spk-tab.on{ background:linear-gradient(120deg,#22d3ee,#a78bfa); color:#08131f }
.spk-tab:not(.on):hover{ color:var(--ink) }

/* Competitor example names under each comparison header */
.comp-eg{ display:block; margin-top:.3rem; font-size:.72rem; font-weight:400; text-transform:none; letter-spacing:0; color:var(--ink-2); opacity:.85; white-space:normal; max-width:16rem }

/* WhatsApp-style round send button (Q&A ask / answer / reply) */
.wa-send{ inline-size:40px; block-size:40px; min-inline-size:40px; border:0; border-radius:50%; background:#25d366; color:#fff; display:inline-flex; align-items:center; justify-content:center; cursor:pointer; padding:0; box-shadow:0 2px 8px rgba(37,211,102,.35); transition:background .15s, transform .1s }
.wa-send:hover{ background:#1ebe57 }
.wa-send:active{ transform:scale(.94) }
.wa-send svg{ margin-inline-start:1px }
/* Q&A identity + timestamps */
.qwho{ color:var(--brand) }
.qtime{ margin-inline-start:.5rem; font-size:.7rem; color:var(--ink-2); opacity:.75; white-space:nowrap }
.qcard.blocked{ opacity:.55 }
.qtools{ display:flex; align-items:center; gap:.4rem; margin-top:.5rem; flex-wrap:wrap }
.qtools .qAnsInput{ flex:1; min-inline-size:8rem; padding:.5rem .65rem; border:1px solid var(--line); border-radius:10px; background:var(--surface-solid); color:var(--ink); font:inherit }
/* Asker CV modal (speaker side) */
.cv-modal{ position:fixed; inset:0; z-index:300; background:rgba(4,7,14,.92);
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
  display:flex; align-items:flex-start; justify-content:center;
  padding:max(1rem, env(safe-area-inset-top)) 1rem max(1rem, env(safe-area-inset-bottom));
  overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch }
.cv-modal > * { margin:auto }
.cv-box{ position:relative; background:var(--surface-solid); border:1px solid var(--line); border-radius:16px; padding:1.25rem 1.25rem 1rem; max-inline-size:420px; inline-size:100%; max-block-size:80vh; overflow-y:auto }
.cv-close{ position:absolute; inset-block-start:.5rem; inset-inline-end:.6rem; border:0; background:transparent; color:var(--ink-2); cursor:pointer; font-size:1rem }

/* Q&A attached image */
.qimg{ display:block; max-inline-size:100%; max-block-size:220px; border-radius:10px; margin:.4rem 0; object-fit:cover }

/* Disabled buttons (e.g. Pause/Stop before a run starts) look grayed out. */
.btn:disabled, .btn[disabled] { opacity: .45; cursor: not-allowed; filter: grayscale(.4); }
/* Speaker run-status pill accents by state. */
.run-status[data-state="live"], .run-status[data-state="livePaused"] { border-color: rgba(34,197,94,.5); }
.run-status[data-state="dry"], .run-status[data-state="dryPaused"] { border-color: rgba(56,189,248,.5); }

/* Viewer-side narration status pill (haven't started / live / paused / stopped). */
.narr-pill { display:inline-flex; align-items:center; gap:.45rem; font-size:.82rem; font-weight:600; border:1px solid var(--line); border-radius:999px; padding:.28rem .7rem; background:var(--surface); color:var(--ink-2); }
.narr-pill .narr-dot { inline-size:9px; block-size:9px; border-radius:50%; background:var(--ink-2); flex:none; }
.narr-pill[data-state="live"] { border-color:rgba(34,197,94,.55); color:#16a34a; }
.narr-pill[data-state="live"] .narr-dot { background:#22c55e; animation:pulse 1.2s ease-in-out infinite; }
.narr-pill[data-state="paused"] { border-color:rgba(251,191,36,.55); color:#d97706; }
.narr-pill[data-state="paused"] .narr-dot { background:#fbbf24; }
.narr-pill[data-state="stopped"] { border-color:rgba(248,113,113,.5); color:#dc2626; }
.narr-pill[data-state="stopped"] .narr-dot { background:#f87171; }
.narr-pill[hidden] { display:none !important; }  /* class display must not override the hidden attribute */

/* Start-narration popup: selectable Live / Dry-run cards. */
.mode-card { display:flex; align-items:center; gap:.7rem; width:100%; text-align:start; background:var(--surface); border:1.5px solid var(--line); border-radius:14px; padding:.85rem 1rem; color:var(--ink); font:inherit; font-size:1rem; cursor:pointer; transition:border-color .12s, background .12s; }
.mode-card:hover { border-color:var(--brand); }
.mode-card .mode-ic { font-size:1.3rem; flex:none; }
.mode-card[aria-pressed="true"] { border-color:var(--brand); background:color-mix(in srgb, var(--brand) 12%, var(--surface)); box-shadow:0 0 0 2px color-mix(in srgb, var(--brand) 30%, transparent) inset; }
.mode-card .mode-txt { flex:1; }
.mode-card .mode-go, .dur-card .mode-go { margin-inline-start:auto; font-size:1.3rem; color:var(--ink-2); flex:none; }
.dur-card { display:flex; align-items:center; gap:.6rem; width:100%; text-align:start; background:var(--surface); border:1.5px solid var(--line); border-radius:14px; padding:.85rem 1rem; color:var(--ink); font:inherit; font-size:1rem; cursor:pointer; transition:border-color .12s, background .12s; }
.dur-card:hover { border-color:var(--brand); background:color-mix(in srgb, var(--brand) 8%, var(--surface)); }

/* Project-settings sub-tabs (Help the narration | Materials for viewers). */
.settabs {
  display: flex; gap: .4rem; flex-wrap: wrap; margin-bottom: .9rem;
  position: sticky; top: 0; z-index: 5;
  background: var(--bg); padding-block: .5rem;
}
.settab { background:var(--surface); border:1px solid var(--line); border-radius:999px; padding:.4rem .9rem; color:var(--ink-2); font:inherit; font-size:.85rem; font-weight:600; cursor:pointer; transition:border-color .12s, background .12s, color .12s; }
.settab:hover { border-color:var(--brand); }
.settab[aria-selected="true"] { border-color:var(--brand); color:var(--brand); background:color-mix(in srgb, var(--brand) 12%, var(--surface)); }
/* The hidden attribute must beat the panels' inline display:grid, otherwise every tab shows at once. */
.settab-panel[hidden] { display:none !important; }

/* Every narration interaction marker -- poll, image, typed note, 👍 -- shares ONE
   compact chip look and size, on both the listener and speaker sides, so they read
   as a consistent set (icon · content · time). */
.cap-poll-pill, .cap-media, .cap-typed, .cap-react,
.spk-media, .spk-typed, .spk-react {
  align-self:flex-start; display:inline-flex; align-items:center; gap:.4rem;
  max-inline-size:100%; padding:.4rem .7rem; margin:.24rem 0;
  border:1px solid var(--line); border-radius:12px; background:var(--surface-solid);
  color:var(--ink); font-size:.92rem; font-weight:400; line-height:1.35; text-align:start;
}
.cap-poll-pill, .cap-media { cursor:pointer; }
/* Who pushed this post (poll / image / PDF) — a small speaker-name badge. */
.cap-post-who { flex:0 0 auto; font-weight:800; color:var(--brand); font-size:.82rem; margin-inline-end:.15rem; white-space:nowrap; }
.cap-poll-pill:hover, .cap-media:hover { border-color:var(--brand); background:color-mix(in srgb, var(--brand) 10%, var(--surface-solid)); }
/* Leading icon */
.cap-poll-ic, .cap-react-ic, .cap-typed-ic, .cap-media-ic,
.spk-media-ic, .spk-typed-ic, .spk-react-ic { font-size:1.05rem; line-height:1; flex:0 0 auto; }
/* Main label / text */
.cap-poll-q, .cap-react-n, .spk-react-n, .spk-typed-tx, .cap-text, .cap-media-cap { font-weight:600; overflow-wrap:anywhere; }
/* Trailing timestamp */
.cap-poll-time, .cap-react-time, .cap-typed-time, .cap-media-time,
.spk-react-time, .spk-media-time, .spk-typed .item-time, .cap-typed .cap-typed-time {
  font-size:.72rem; opacity:.7; flex:0 0 auto; margin-inline-start:.15rem; white-space:nowrap; font-weight:400;
}
/* Reactor's name on a 👍 marker (hidden when anonymous / no name). */
.spk-react-who, .cap-react-who { font-weight:700; font-size:.82rem; }
.spk-react-who:empty, .cap-react-who:empty { display:none; }
.cap-react.bump, #thumbFab.tapped, #confuseFab.tapped { animation:reactbump .28s ease; }
/* The audience "I don't understand" alert in the speaker's timeline. */
.spk-confuse { align-self:stretch; margin:.24rem 0; padding:.45rem .7rem; border-radius:10px; border:1px solid #f59e0b; background:color-mix(in srgb, #f59e0b 15%, var(--surface-solid)); color:var(--ink); font-weight:600; font-size:.9rem; }
@keyframes reactbump { 0%{ transform:scale(1); } 40%{ transform:scale(1.18); } 100%{ transform:scale(1); } }
/* On the speaker side, a 👍 comes FROM the audience -- align it to the right (and
   tint it) so it reads as incoming, not something the speaker sent. */
.spk-react { align-self:flex-end; border-color:var(--brand); background:color-mix(in srgb, var(--brand) 10%, var(--surface-solid)); }

/* Per-line ⋯ kebab: every timeline line is wrapped in a .line-row that also holds
   a small ⋯ button; its menu (Delete / Reply / DM) is portaled to <body>. */
.line-row { display:flex; align-items:center; gap:.25rem; inline-size:100%; box-sizing:border-box; }
.line-row-end { flex-direction:row-reverse; }
.line-row[data-kind="final"] > :first-child,
.line-row[data-kind="typed"] > :first-child { flex:1 1 auto; min-inline-size:0; }
.line-row:not(.line-row-end) > .line-kebab { margin-inline-start:auto; }
.line-kebab {
  flex:0 0 auto; align-self:center; border:0; background:transparent; color:var(--ink-2);
  cursor:pointer; font-size:1.2rem; line-height:1; padding:.05rem .35rem; border-radius:6px; opacity:.6;
}
.line-kebab:hover, .line-kebab:focus-visible { opacity:1; background:color-mix(in srgb, var(--ink) 10%, transparent); outline:none; }
/* Touch phones (what a speaker actually holds) have no hover to reveal the ⋯, so
   keep it clearly visible there rather than faded. */
@media (hover: none), (pointer: coarse) {
  .line-kebab { opacity:.85; color:var(--ink); }
}
.line-menu {
  position:fixed; z-index:2147483000; min-inline-size:180px; max-inline-size:min(92vw,260px);
  /* A distinct, brand-tinted panel so the post menu floats clearly above the app,
     instead of blending into the timeline / input (which share var(--surface-solid)). */
  background:color-mix(in srgb, var(--brand) 14%, var(--surface-solid));
  border:1px solid color-mix(in srgb, var(--brand) 42%, var(--line)); border-radius:12px;
  box-shadow:0 12px 34px rgba(0,0,0,.4); padding:.3rem; display:flex; flex-direction:column; gap:.1rem;
}
/* display:flex above would otherwise beat the `hidden` attribute (which is only
   display:none by default), leaving the menu stuck open. Force it closed. */
.line-menu[hidden] { display:none !important; }
/* The "display messages" settings menu (⚙ beside the input) gets a distinct,
   brand-tinted background so it reads as a panel floating above the app, not part
   of the input row / timeline (which share var(--surface-solid)). */
#spkFilterMenu {
  background:color-mix(in srgb, var(--brand) 14%, var(--surface-solid));
  border-color:color-mix(in srgb, var(--brand) 42%, var(--line));
  box-shadow:0 12px 34px rgba(0,0,0,.4);
}
/* Speaker's "display messages" filter: hide chosen kinds in the timeline. */
#spkHistory.flt-hide-narration .line-row[data-kind="final"],
#spkHistory.flt-hide-polls .line-row[data-kind="poll"],
#spkHistory.flt-hide-private .line-row[data-kind="dm"],
#spkHistory.flt-hide-speaker .line-row[data-kind="typed"],
#spkHistory.flt-hide-speaker .line-row[data-kind="media"] { display:none !important; }
.line-menu .flt-head { font-weight:700; font-size:.78rem; padding:.25rem .5rem .1rem; color:var(--ink-2); text-transform:uppercase; letter-spacing:.04em; }
.line-menu .flt-row { display:flex; align-items:center; gap:.5rem; padding:.4rem .55rem; font-size:.9rem; cursor:pointer; border-radius:8px; color:var(--ink); }
.line-menu .flt-row:hover { background:color-mix(in srgb, var(--brand) 10%, transparent); }
.line-menu .flt-row input { inline-size:16px; block-size:16px; flex:0 0 auto; }
.line-menu .flt-sep { block-size:1px; background:var(--line); margin:.25rem .3rem; }
.line-menu button {
  display:flex; align-items:center; gap:.5rem; inline-size:100%; text-align:start;
  background:transparent; border:0; color:var(--ink); cursor:pointer;
  padding:.55rem .6rem; border-radius:8px; font:inherit; font-size:.9rem;
}
.line-menu button:hover { background:color-mix(in srgb, var(--brand) 12%, transparent); }
/* A hidden menu item must actually hide: the display:flex above otherwise beats the
   [hidden] attribute, which is what left "View media" (on non-media) and "Block this
   listener" (on the speaker's own posts) still showing despite the JS hiding them. */
.line-menu button[hidden] { display:none !important; }
.line-menu .line-menu-del { color:#dc2626; }
.line-menu .line-menu-del:hover { background:color-mix(in srgb, #dc2626 14%, transparent); }
/* A just-sent line flashes once so it is unmistakable. */
.line-flash { animation:lineFlash 1.6s ease; border-radius:12px; }
@keyframes lineFlash {
  0%   { background:color-mix(in srgb, var(--brand) 45%, transparent); }
  100% { background:transparent; }
}

/* Pinned line kept at the top of the narration (host message + up to two links,
   plus a quick poll on the demo). Flex:0 so the timeline scrolls beneath it. */
.pinned-bar {
  align-self:stretch; margin-block-end:.3rem; padding:.3rem .5rem; border-radius:9px;
  border:1px solid color-mix(in srgb, var(--brand) 35%, var(--line));
  background:color-mix(in srgb, var(--brand) 8%, var(--surface-solid));
  display:flex; flex-direction:column; gap:.25rem;
}
.pinned-main { display:flex; align-items:baseline; flex-wrap:wrap; gap:.35rem; }
.pinned-ic { flex:0 0 auto; font-size:.8rem; }
/* At most two tight lines, then ellipsis. */
.pinned-text {
  font-weight:600; font-size:.8rem; line-height:1.25; overflow-wrap:anywhere;
  display:-webkit-box; -webkit-line-clamp:2; line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.pinned-link {
  flex:0 0 auto; display:inline-flex; align-items:center; gap:.15rem; text-decoration:none;
  padding:.05rem .4rem; border-radius:999px; font-size:.72rem; font-weight:600;
  border:1px solid var(--brand); color:var(--brand); background:transparent;
}
.pinned-link:hover { background:color-mix(in srgb, var(--brand) 14%, transparent); }
/* Pinned resources: a ⋯ kebab opens a popup of tappable cards (links / PDFs / slides). */
/* Right side of the pinned line: reception meter, then the ⋯ resources kebab. */
.pinned-right { margin-inline-start:auto; display:inline-flex; align-items:center; gap:.5rem; flex:0 0 auto; }
.pinned-res-wrap { position:relative; display:inline-flex; flex:0 0 auto; margin-inline-start:auto; }
.pinned-right .pinned-res-wrap { margin-inline-start:0; }   /* the container already right-aligns the group */
.pinned-kebab { border:1px solid var(--line); background:var(--surface-solid); color:var(--ink-2);
  cursor:pointer; border-radius:999px; inline-size:1.7rem; block-size:1.7rem; line-height:1; font-size:1rem;
  display:inline-flex; align-items:center; justify-content:center; padding:0; }
.pinned-kebab:hover { color:var(--ink); border-color:var(--brand); }
.pinned-res-pop { position:absolute; inset-block-start:calc(100% + 6px); inset-inline-end:0; z-index:60;
  min-inline-size:min(80vw,260px); max-inline-size:min(88vw,320px);
  background:color-mix(in srgb, var(--brand) 14%, var(--surface-solid));
  border:1px solid color-mix(in srgb, var(--brand) 45%, var(--line)); border-radius:12px;
  box-shadow:0 12px 34px rgba(0,0,0,.34); padding:.4rem; display:flex; flex-direction:column; gap:.3rem; }
.pinned-res-pop[hidden] { display:none; }
.pinned-res-head { margin:.15rem .4rem .25rem; font-size:.7rem; font-weight:800; text-transform:uppercase;
  letter-spacing:.04em; color:var(--ink-2); text-align:end; }
/* Cards are laid out right-to-left: icon on the right, label right-aligned, ↗ on the left. */
.pinned-res-card { display:flex; flex-direction:row-reverse; align-items:center; gap:.55rem; text-decoration:none; color:var(--ink);
  padding:.5rem .55rem; border:1px solid var(--line); border-radius:10px; background:var(--surface-solid); }
.pinned-res-card:hover { border-color:var(--brand); background:color-mix(in srgb, var(--brand) 10%, var(--surface-solid)); }
.pinned-res-ic { flex:0 0 auto; font-size:1.15rem; }
.pinned-res-body { flex:1 1 auto; min-inline-size:0; display:flex; flex-direction:column; align-items:flex-end; text-align:end; }
.pinned-res-lbl { font-size:.85rem; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pinned-res-sub { font-size:.68rem; color:var(--ink-2); }
.pinned-res-go { flex:0 0 auto; color:var(--ink-2); }
.pinned-poll { display:flex; flex-direction:column; gap:.25rem; }
.pinned-poll-q { font-weight:700; font-size:.78rem; }
.pinned-poll-opts { display:flex; flex-wrap:wrap; gap:.3rem; }
.pinned-poll-opt {
  flex:1 1 auto; min-inline-size:80px; text-align:start; cursor:pointer; font:inherit; font-size:.76rem;
  padding:.25rem .5rem; border-radius:8px; border:1px solid var(--line);
  background:var(--surface-solid); color:var(--ink); position:relative; overflow:hidden;
}
.pinned-poll-opt:hover { border-color:var(--brand); }
.pinned-poll-opt .pp-fill { position:absolute; inset-block:0; inset-inline-start:0; background:color-mix(in srgb, var(--brand) 22%, transparent); z-index:0; }
.pinned-poll-opt .pp-lab { position:relative; z-index:1; display:flex; justify-content:space-between; gap:.5rem; }
.pinned-poll-opt.pp-mine { outline:2px solid var(--brand); }

/* A quoted snippet shown above a reply / inside a DM. */
.line-quote {
  display:block; border-inline-start:3px solid var(--brand); padding:.15rem .5rem; margin:.1rem 0;
  background:color-mix(in srgb, var(--brand) 8%, transparent); border-radius:4px;
  font-size:.8rem; color:var(--ink-2); overflow-wrap:anywhere; opacity:.9;
}
.line-quote-inline { margin-inline-end:.35rem; }

/* Private DM line — a distinct locked, tinted chip. */
.cap-dm, .spk-dm {
  align-self:flex-start; display:inline-flex; align-items:center; flex-wrap:wrap; gap:.35rem;
  max-inline-size:100%; padding:.4rem .7rem; margin:.24rem 0;
  border:1px solid color-mix(in srgb, #a855f7 45%, var(--line)); border-radius:12px;
  background:color-mix(in srgb, #a855f7 12%, var(--surface-solid)); color:var(--ink); font-size:.92rem; line-height:1.35;
}
.cap-dm-out { align-self:flex-end; }
.cap-dm-ic { flex:0 0 auto; }
.cap-dm-who { font-weight:700; font-size:.8rem; color:#a855f7; }
.cap-dm-tx { overflow-wrap:anywhere; }
.cap-dm-orig { overflow-wrap:anywhere; opacity:.55; font-size:.82rem; font-style:italic; flex:1 1 100%; }
.cap-dm-time { font-size:.72rem; opacity:.7; flex:0 0 auto; white-space:nowrap; }
/* An audience question in the timeline: distinct from a private DM (amber, not purple). */
.cap-q { border-color:color-mix(in srgb, #f59e0b 55%, var(--line)); background:color-mix(in srgb, #f59e0b 13%, var(--surface-solid)); }
.cap-q .cap-dm-who { color:#f59e0b; }
.cap-q .cap-dm-tx { font-weight:600; }
/* A private message still being delivered (queued in the outbox): dimmed with an ⏳. */
.cap-dm-pending { opacity:.55; }

/* Reply / DM compose dialog (portaled to <body>). */
.line-compose-ov {
  position:fixed; inset:0; z-index:2147483000; display:flex; align-items:center; justify-content:center;
  padding:1rem; background:rgba(4,10,20,.6);
}
.line-compose {
  /* Tinted like the + and 📎 menus, so a popup never reads as part of the page behind it
     (delete lines, block, reply / private message, read aloud). */
  inline-size:100%; max-inline-size:460px; color:var(--ink);
  background:color-mix(in srgb, var(--brand) 16%, var(--surface-solid));
  border:1px solid color-mix(in srgb, var(--brand) 45%, var(--line)); border-radius:16px; padding:1rem; display:flex; flex-direction:column; gap:.6rem;
  box-shadow:0 18px 50px rgba(0,0,0,.5);
}
.line-compose-head { font-weight:800; font-size:1rem; }
.line-compose-ta {
  inline-size:100%; box-sizing:border-box; resize:vertical; min-block-size:4.5em;
  padding:.6rem .7rem; border:1px solid var(--line); border-radius:10px;
  background:var(--surface-solid); color:var(--ink); font:inherit; font-size:.95rem;
}
.line-compose-row { display:flex; gap:.5rem; justify-content:flex-end; }

/* Reader ⋯ tools menu -- tidy, every row the same height. */
.tools-menu .tools-item, .tools-menu .tools-field, .tools-menu .tools-fontrow button {
  box-sizing:border-box; block-size:2.35rem; min-block-size:2.35rem; font-size:.9rem; border-radius:10px;
}
.tools-menu .tools-item { display:flex; align-items:center; justify-content:flex-start; gap:.4rem; padding:0 .6rem; inline-size:100%; }
.tools-menu .tools-item:hover { background:color-mix(in srgb, var(--brand) 10%, transparent); }
.tools-menu .tools-label { margin:.4rem .25rem .05rem; font-size:.64rem; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-2); opacity:.7; }
.tools-menu .tools-field { inline-size:100%; padding:0 .5rem; border:1px solid var(--line); background:var(--surface-solid); color:var(--ink); }
.tools-menu .tools-fontrow { display:flex; gap:.4rem; }
.tools-menu .tools-fontrow button { flex:1; justify-content:center; padding:0; }
.tools-menu .tools-sep { block-size:1px; background:var(--line); margin:.4rem .15rem; flex:0 0 auto; }
/* 👍 FAB shows the viewer's remaining star balance under the thumb. */
#thumbFab { flex-direction:column; gap:0; line-height:1; }
#thumbFab .star-bal { font-size:.58rem; font-weight:800; opacity:.9; margin-block-start:1px; }
/* 👍 as an item in the listener's 📎 menu (moved there by listener-voice.js). */
#thumbFab.dm-menu-item { position:static !important; flex-direction:row; justify-content:flex-start; gap:.55rem; inline-size:100%; block-size:auto; padding:.55rem .7rem; border:0; border-radius:8px; background:transparent; box-shadow:none; font:inherit; font-size:.95rem; color:var(--ink); cursor:pointer; text-align:start; }
#thumbFab.dm-menu-item:hover { background:rgba(127,127,127,.14); }
#thumbFab.dm-menu-item .dm-menu-lbl { flex:1 1 auto; white-space:nowrap; }
#thumbFab.dm-menu-item .star-bal { font-size:.72rem; margin:0; opacity:.7; }

/* Collapsible settings sections (accordion). Every section starts collapsed. */
details.setacc { border:1px solid var(--line); border-radius:14px; background:var(--surface-solid); padding:.2rem .9rem; margin-top:.9rem; }
details.setacc > summary { cursor:pointer; font-weight:700; font-size:.95rem; list-style:none; display:flex; align-items:center; gap:.45rem; padding:.7rem 0; color:var(--ink); }
details.setacc > summary::-webkit-details-marker { display:none; }
details.setacc > summary::after { content:'▸'; margin-inline-start:auto; opacity:.55; transition:transform .15s; }
details.setacc[open] > summary::after { transform:rotate(90deg); }
details.setacc > summary:hover { color:var(--brand); }
details.setacc[open] > summary { border-bottom:1px solid var(--line); margin-bottom:.6rem; }
details.setacc > .setacc-body { padding-bottom:.7rem; }

/* Per-field help: a small "?" trigger opens a popup explaining the field. */
.fhelp { display:inline-flex; align-items:center; justify-content:center; inline-size:17px; block-size:17px; padding:0; border:1px solid var(--line); border-radius:50%; background:var(--surface-solid); color:var(--ink-2); font-size:.72rem; font-weight:700; line-height:1; cursor:pointer; flex:0 0 auto; }
.fhelp:hover, .fhelp:focus-visible { color:var(--brand); border-color:var(--brand); }
.help-pop-backdrop { position:fixed; inset:0; background:rgba(4,7,14,.92);
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
  display:flex; align-items:flex-start; justify-content:center;
  padding:max(1rem, env(safe-area-inset-top)) 1rem max(1rem, env(safe-area-inset-bottom));
  overflow-y:auto; overscroll-behavior:contain; z-index:1000; }
.help-pop { margin:auto; max-inline-size:400px; width:100%; background:var(--surface-solid); border:1px solid var(--line); border-radius:16px; padding:1.15rem 1.25rem; box-shadow:0 24px 60px rgba(0,0,0,.45); }
.help-pop h4 { margin:0 0 .5rem; color:var(--ink); font-size:1rem; }
.help-pop p { margin:0; color:var(--ink-2); font-size:.9rem; line-height:1.55; }

/* Small pill used to summarise project settings on the dashboard. */
.chip { display:inline-flex; align-items:center; gap:.3rem; font-size:.76rem; border:1px solid var(--line); border-radius:999px; padding:.2rem .55rem; background:var(--surface); color:var(--ink-2); white-space:nowrap; }
.gcell form button:hover { filter:brightness(1.1); }

/* Pause/Stop split-button "all speakers" pop-up menu. */
.ctl-menu { position:absolute; inset-block-start:calc(100% + 4px); inset-inline-end:0; z-index:30; background:var(--surface-solid); border:1px solid var(--line); border-radius:12px; box-shadow:0 12px 30px rgba(0,0,0,.28); padding:.3rem; min-inline-size:200px; }
.ctl-menu button { display:block; width:100%; text-align:start; background:transparent; border:0; color:var(--ink); font:inherit; font-size:.88rem; padding:.55rem .7rem; border-radius:8px; cursor:pointer; }
.ctl-menu button:hover { background:var(--surface); }

/* Live speaker stats tiles. */
.stat-tile { display:flex; flex-direction:column; align-items:center; gap:.15rem; border:1px solid var(--line); border-radius:12px; padding:.55rem .3rem; background:var(--surface-solid); }
.stat-tile .stat-num { font-size:1.5rem; font-weight:800; color:var(--brand); line-height:1; }
.stat-tile .stat-lbl { font-size:.68rem; color:var(--ink-2); text-align:center; }


/* ---- start wizard -------------------------------------------------------
   A phone keyboard can take half the screen, so this scrolls rather than
   centring into a space that is no longer there. align-items:flex-start with
   margin:auto on the panel gives both: centred when it fits, scrollable when
   it does not -- which align-items:center alone cannot do, because it clips
   the top of anything taller than the viewport with no way to reach it. */
.start-modal {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(4,7,14,.92);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  display: grid;                      /* the script only toggles none/grid */
  align-content: center;              /* centre the card vertically (it scrolls inside if tall) */
  justify-items: center;
  padding: max(1.5vh, .6rem) max(1rem, env(safe-area-inset-right))
           max(1rem, env(safe-area-inset-bottom)) max(1rem, env(safe-area-inset-left));
  overflow: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.start-modal > .start-panel {
  margin: 0;
  max-inline-size: 440px; inline-size: 100%;
  border-radius: 18px; position: relative;
  max-block-size: 100%;               /* never taller than the space it sits in */
  overflow-y: auto;                   /* long steps scroll inside the card */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
/* The close button sits over the corner, so the heading is kept clear of it
   rather than running underneath. */
.start-modal .eyebrow, .start-modal h3 { padding-inline-end: 3rem; }
/* 0.3rem x 0.6rem of padding is about 28px. Thumbs need 44. */
.start-modal #startCancel {
  min-inline-size: 44px; min-block-size: 44px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.05rem; line-height: 1;
}
@media (max-width: 480px) {
  .start-modal > .start-panel { border-radius: 16px; padding: 1.15rem 1rem 1.3rem; }
  /* Full-width rows with a comfortable target height -- these are the whole
     interaction on this screen. */
  .start-modal .mode-card, .start-modal .dur-card { padding: 1rem .9rem; min-block-size: 52px; }
  .start-modal h3 { font-size: 1.15rem; }
  .start-modal #startName, .start-modal #startNameNext { min-block-size: 52px; }
  /* 16px or iOS zooms the page in when the field takes focus. */
  .start-modal #startName { font-size: 16px; }
}


/* wizard: compact enough to centre */
/* margin:auto on the panel centres it whenever it fits and top-aligns it when
   it does not, so that it can scroll. The way to have it centred on a phone is
   therefore to make it fit -- not to force alignment, which would clip the top
   of anything taller than the screen with no way to reach it.
   !important because the spacing it is overriding lives in style attributes,
   and an inline style beats a stylesheet however specific the selector. */
@media (max-width: 560px) {
  .start-modal .eyebrow { font-size: .68rem; margin-block-end: .1rem !important; }
  .start-modal h3 { font-size: 1.1rem; margin-block-end: .15rem !important; line-height: 1.25; }
  .start-modal .muted { font-size: .8rem; line-height: 1.35; margin-block-end: .7rem !important; }
  .start-modal label { margin-block-start: .55rem !important; margin-block-end: .2rem !important; }
  .start-modal #startName, .start-modal #startLang { padding: .6rem .7rem !important; }
  .start-modal #startNameNext { margin-block-start: .7rem !important; padding: .75rem !important; }
  .start-modal .wallgrid, .start-modal #startModeChoice, .start-modal #durChoice { gap: .45rem !important; }
  .start-modal .mode-card, .start-modal .dur-card { min-block-size: 48px; padding: .8rem .85rem !important; }
}
/* Very short screens -- a phone with the keyboard up is often under 380px. */
@media (max-height: 620px) {
  .start-modal .muted { display: none; }        /* the hint is the first thing to go */
  .start-modal > .start-panel { padding-block: .9rem !important; }
}


/* ---- listener toolbar ---------------------------------------------------
   Sticky rather than fixed: it keeps its place in the flow, so nothing has to
   be padded to make room for it and it cannot cover the end of the page.
   The background is opaque on purpose -- text scrolling underneath a
   translucent bar is harder to read than the bar is useful. */
.read-bar {
  position: sticky;
  inset-block-start: 0;
  z-index: 30;
  background: var(--bg);
  padding-block-end: .45rem;
  margin-inline: -2px;      /* cover the parent's edge as content passes under */
  padding-inline: 2px;
}
/* A hairline only once something has scrolled beneath it. */
.read-bar::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  block-size: 1px;
  background: var(--line);
  opacity: .6;
}


/* Every overlay behaves the same way, however it was written. The panel inside
   centres while it fits and the overlay scrolls once it does not, so a dialog
   is never partly above the top of the screen. */
.sh-modal { position:fixed; inset:0; z-index:200; background:rgba(4,7,14,.92);
  -webkit-backdrop-filter:blur(4px); backdrop-filter:blur(4px);
  align-items:flex-start; justify-content:center;
  padding:max(1rem, env(safe-area-inset-top)) 1rem max(1rem, env(safe-area-inset-bottom));
  overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch }
.sh-modal > * { margin:auto }


/* The hint is the first thing to go when there is no room for it -- the fields
   and the button are what the step is for. */
@media (max-height: 700px) {
  .start-modal .muted { display: none; }
}


/* ---- saved sessions ----------------------------------------------------
   A transcript is long and there are many of them; the useful view of the list
   is which sessions exist, not all of their words at once. Closed by default,
   and the whole header opens it. */
.saved-entry > summary { list-style: none; }
.saved-entry > summary::-webkit-details-marker { display: none; }
.saved-entry > summary::after {
  content: '⌄';
  margin-inline-start: auto;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--ink-2);
  transition: transform .15s ease;
}
.saved-entry[open] > summary::after { transform: rotate(180deg); }
.saved-entry > summary:hover { color: var(--ink); }
.saved-entry > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 8px; }


/* A message from the speaker is addressed to this reader and is still unseen,
   so it pulses briefly rather than sitting as another quiet number. */
.badge-msg { animation: badgePulse 1.6s ease-in-out 3; }
@keyframes badgePulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.18); }
}
@media (prefers-reduced-motion: reduce) { .badge-msg { animation: none; } }


/* whatsapp-style interaction pane: the thread scrolls, the composer stays put.
   The pane is shown by clearing an inline display:none, so this rule applies. */
#qnaSection {
  display: flex; flex-direction: column;
  max-block-size: min(68vh, 620px);
}
#qnaSection > .wa-scroll {
  flex: 1 1 auto; min-block-size: 5rem;
  overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: .7rem;
  padding-inline-end: .25rem;
}
#qnaSection > #qAskForm, #qnaSection > #bcastForm {
  flex: 0 0 auto;                       /* never squeezed by a long thread */
  margin-block: .6rem 0;
  padding-block-start: .6rem;
  border-block-start: 1px solid var(--line);
}


/* The "replying to" bar above the composer, and the per-message ⋮ anchor. */
#bcastReply {
  display: flex; align-items: flex-start; gap: .5rem;
  padding: .45rem .55rem; margin-block-end: .4rem;
  border-inline-start: 3px solid var(--brand);
  border-radius: 8px; background: var(--surface);
}
#bcastReply[hidden] { display: none; }
#bcastReply .reply-quote { flex: 1 1 auto; min-inline-size: 0; display: flex; flex-direction: column; gap: .1rem; }
#bcastReply .reply-who { font-size: .74rem; font-weight: 800; color: var(--brand); }
#bcastReply .reply-text {
  font-size: .8rem; color: var(--ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;   /* one line, like a chat quote */
}
#bcastReply .btn { padding: .2rem .45rem; font-size: .8rem; flex: 0 0 auto; }
.qmenu-wrap { position: relative; display: inline-flex; }


/* The per-tab copy / read-aloud pair, sitting at the head of its own pane. */
.pane-tools { display: flex; justify-content: flex-end; gap: .3rem; margin-block-end: .4rem; }
.pane-tools .btn { padding: .35rem .6rem; }


/* composers grow with the message: one line at rest, taller as it is typed,
   and never past a third of the pane -- the thread above still matters. */
#qAskInput, #bcastInput {
  resize: none; overflow-y: auto;
  min-block-size: 2.6rem; max-block-size: 8.5rem;
}


.navdrop-email {
  display: inline-block; max-inline-size: 16ch;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  vertical-align: bottom;
}


/* The per-message menu is positioned in script when open, so it must not keep
   the anchored offsets that .ctl-menu applies. */
.qMenu { min-inline-size: 9rem; }
.qMenu button { text-align: end; }


/* The session code, so both sides can see at a glance that they match. */
.room-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .72rem; color: var(--ink-2);
  border: 1px solid var(--line); border-radius: 999px;
  padding: .1rem .45rem; align-self: center; white-space: nowrap;
}


/* the controls ride with the name, so they never take a line of their own */
.qcard { position: relative; }
#qList .qtools {
  display: inline-flex;
  position: static;
  margin: 0 0 0 .3rem;
  margin-inline-start: .3rem; margin-inline-end: 0;
  gap: .15rem; flex-wrap: nowrap;
  vertical-align: middle;
}
#qList .qtools .btn { padding: .05rem .3rem; font-size: .8rem; line-height: 1.2; }


/* who is on which side: the speaker's words on one edge, the audience's on the
   other, so the thread reads like a conversation rather than a list. Logical
   (start/end) rather than left/right, so it mirrors correctly in Hebrew. */
#qList { align-items: stretch; }
#qList > .qcard {
  align-self: flex-end;
  max-inline-size: 88%;
  border-start-end-radius: 4px;      /* the tail points at its own side */
}



/* the name (and its menu) on the first line, the words underneath */
.qwho-line {
  display: flex; align-items: center; gap: .35rem;
  margin-block-end: .2rem; font-size: .78rem;
}
.qwho-line .qwho, .qwho-line b { font-weight: 800; color: var(--brand); }
#qList .qtools { margin-inline-start: .1rem; }   /* immediately after the name, not pushed to the far edge */


/* the menu must not read as part of the thread */
.qMenu {
  background: #1c2a4d;
  border-color: color-mix(in srgb, var(--brand) 45%, var(--line));
  box-shadow: 0 16px 40px rgba(0, 0, 0, .55);
}
.qMenu button { color: var(--ink); }
.qMenu button:hover { background: color-mix(in srgb, var(--brand) 22%, transparent); }


/* Instrumental stretches: a marker, not a transcript line. */
.music-note {
  align-self: center; margin: .5rem auto;
  padding: .3rem .8rem; border-radius: 999px;
  border: 1px dashed var(--line); color: var(--ink-2);
  font-size: .82rem; letter-spacing: .02em;
  background: var(--surface);
}


/* One card per song: title, its lines, and a way to remove it. */
.work-card {
  border: 1px solid var(--line); border-radius: 12px;
  padding: .6rem .7rem; margin-block-end: .5rem;
  background: var(--surface);
}
.work-head { display: flex; gap: .5rem; align-items: center; margin-block-end: .4rem; }
.work-body[hidden] { display: none !important; }   /* collapsed song: hide body, keep the title row */
.work-collapse[aria-expanded="true"] { opacity: .95 !important; }
.work-card:last-child { margin-block-end: 0; }
.work-card .work-title {
  flex: 1 1 auto; min-inline-size: 0;
  padding: .45rem .6rem; border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface-solid); color: var(--ink); font-weight: 700;
}
.work-card .work-del { padding: .3rem .55rem; flex: 0 0 auto; }
.work-card .work-lyrics {
  inline-size: 100%; resize: vertical;
  padding: .5rem .6rem; border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface-solid); color: var(--ink);
  font-size: .9rem; line-height: 1.5;
}

.music-time { margin-inline-start: .5rem; font-size: .72rem; opacity: .7; }

.work-audio { display: flex; align-items: center; gap: .6rem; margin-block-start: .5rem; }
.work-audio .btn { padding: .3rem .6rem; font-size: .8rem; }
.work-state { font-size: .78rem; }


/* Recordings tab */
.rec-rights { display: flex; gap: .55rem; align-items: flex-start; font-size: .86rem;
  border: 1px solid var(--line); border-radius: 12px; padding: .6rem .7rem; background: var(--surface); }
.rec-choice { display: flex; gap: 1.2rem; flex-wrap: wrap; font-size: .86rem; }
.rec-track { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap;
  border: 1px solid var(--line); border-radius: 12px; padding: .5rem .7rem; margin-block-end: .4rem; }
.rec-track .grow { flex: 1 1 auto; min-inline-size: 0; }
.rec-player { border: 1px solid var(--line); border-radius: 14px; padding: .7rem; background: var(--surface); }
.rec-head { display: flex; justify-content: space-between; align-items: center; margin-block-end: .5rem; }
.rec-lines { max-block-size: 260px; overflow-y: auto; margin-block-start: .6rem;
  display: flex; flex-direction: column; gap: .1rem; }
.rec-lines div { padding: .18rem .4rem; border-radius: 7px; font-size: .88rem; color: var(--ink-2); }
/* the line that should be sounding right now */
.rec-lines div.on { background: color-mix(in srgb, var(--brand) 22%, transparent); color: var(--ink); font-weight: 700; }

.src-choice { display: flex; gap: 1.1rem; flex-wrap: wrap; font-size: .88rem; }
.src-choice label { display: inline-flex; align-items: center; gap: .35rem; cursor: pointer; }


/* A continuation of the same speaker: the colour bar stays to keep the thread,
   but softened, so a run of lines reads as one voice rather than many entries. */
/* the colour itself is cleared inline by the line builder; this only softens
   the timestamp on a continued line */
.cap-line.cap-cont .cap-time { opacity: .55; }


/* A question for the room: the question, up to four answers, and how long it stays open. */
/* Each saved poll is a clearly separated, numbered card so two polls never blur
   together: an accent left edge, its own tint, spacing and a "Poll N" badge. */
.poll-card { border: 1px solid var(--line); border-inline-start: 4px solid var(--brand); border-radius: 12px;
  padding: .75rem .85rem; margin-block-end: 1rem; background: color-mix(in srgb, var(--brand) 4%, var(--surface));
  box-shadow: 0 1px 5px rgba(0,0,0,.07); }
.poll-num-row { display: flex; align-items: center; gap: .5rem; margin-block-end: .5rem; }
.poll-num { flex: 0 0 auto; font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em;
  color: #fff; background: var(--brand); border-radius: 999px; padding: .12rem .55rem; white-space: nowrap; }
.poll-num-row .poll-name { flex: 1 1 auto; min-inline-size: 0; font-weight: 700; }
.poll-num-row .poll-del { flex: 0 0 auto; padding: .3rem .55rem; }
.poll-head { display: flex; gap: .5rem; align-items: center; margin-block-end: .45rem; }
.poll-card .poll-q { flex: 1 1 auto; min-inline-size: 0; font-weight: 700; }
.poll-card .poll-del { padding: .3rem .55rem; flex: 0 0 auto; }
.poll-answers { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: .35rem; }
.poll-card input.field { padding: .4rem .55rem; border: 1px solid var(--line); border-radius: 9px;
  background: var(--surface-solid); color: var(--ink); font-size: .85rem; inline-size: 100%; }
.poll-secs { display: block; margin-block-start: .45rem; font-size: .78rem; color: var(--ink-2); }
.poll-secs input { inline-size: 5rem; margin-inline-start: .3rem; }


/* A question on the audience's screen. The bar behind each answer only appears
   once this person has voted, or the question has closed. */
.poll-live { border: 1px solid color-mix(in srgb, var(--brand) 40%, var(--line));
  border-radius: 14px; padding: .7rem .8rem; margin-block: .4rem; background: var(--surface); }
.poll-q-text { font-weight: 800; margin-block-end: .55rem; }
.poll-opts { display: flex; flex-direction: column; gap: .35rem; }
.poll-opt { position: relative; overflow: hidden; text-align: start;
  border: 1px solid var(--line); border-radius: 10px; padding: .5rem .65rem;
  background: var(--surface-solid); color: var(--ink); font: inherit; font-size: .9rem; cursor: pointer; }
.poll-opt:hover { border-color: var(--brand); }
.poll-live.voted .poll-opt { cursor: default; }
.poll-opt.shown::before { content: ''; position: absolute; inset-block: 0; inset-inline-start: 0;
  inline-size: var(--fill, 0%); background: color-mix(in srgb, var(--brand) 22%, transparent); z-index: 0; }
.poll-opt.mine { border-color: var(--brand); font-weight: 700; }
.poll-count { position: relative; z-index: 1; float: inline-end; font-size: .8rem; color: var(--ink-2); }
.poll-note { margin-block-start: .5rem; font-size: .78rem; }

.dry-chip { margin: .5rem 0; padding: .35rem .7rem; border-radius: 999px; text-align: center;
  font-size: .8rem; font-weight: 700; color: #0b1226;
  background: color-mix(in srgb, var(--amber) 80%, white); }

.cmt-private { font-size: .74rem; line-height: 1.35; margin: .25rem 0 .35rem; }


/* "There is a newer version" — offered, never forced. */
#shoora-update {
  position: fixed; inset-block-end: max(1rem, env(safe-area-inset-bottom));
  inset-inline: 1rem; margin-inline: auto; max-inline-size: 30rem; z-index: 9998;
  display: flex; gap: .6rem; align-items: center; flex-wrap: wrap;
  padding: .7rem .9rem; border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--brand) 45%, var(--line));
  background: var(--surface-solid); box-shadow: 0 18px 40px rgba(0,0,0,.45);
  font-size: .86rem;
}
#shoora-update .su-text { flex: 1 1 12rem; min-inline-size: 0; }
#shoora-update .btn { padding: .35rem .8rem; font-size: .82rem; }


/* Offline is not the same as nobody talking, and it should not look the same. */
.reconn-note {
  position: fixed; inset-block-start: max(.6rem, env(safe-area-inset-top));
  inset-inline: 1rem; margin-inline: auto; max-inline-size: 26rem; z-index: 9997;
  padding: .5rem .8rem; border-radius: 999px; text-align: center; font-size: .8rem;
  color: #0b1226; background: color-mix(in srgb, var(--amber) 85%, white);
  box-shadow: 0 10px 26px rgba(0,0,0,.35);
}


/* Which words the audience is getting, and who decides. */
.follow-row { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap;
  margin: .6rem 0; padding: .5rem .7rem; border: 1px solid var(--line);
  border-radius: 12px; background: var(--surface); font-size: .82rem; }
.follow-label { font-weight: 700; }
.follow-pick { display: inline-flex; flex-wrap: wrap; gap: .25rem; max-width: 100%; }
.follow-pick button { font: inherit; font-size: .8rem; padding: .25rem .6rem; cursor: pointer;
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface-solid); color: var(--ink-2); }
.follow-pick button.on { border-color: var(--brand); color: var(--ink); font-weight: 700; }
.narr-select { font: inherit; font-size: .82rem; padding: .3rem 1.6rem .3rem .6rem; cursor: pointer;
  border: 1px solid var(--line); border-radius: 8px; background: var(--surface-solid); color: var(--ink);
  max-width: 100%; appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%23888' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .55rem center; }
.narr-select:focus { outline: none; border-color: var(--brand); }
.follow-now { flex: 1 1 100%; font-size: .76rem; }
.follow-now.adrift { color: var(--amber); }

/* A word the recogniser only half-heard. Shown, not hidden -- but shown as a
   question, so nobody reads a guess as though it were what was said. */
/* One coherent RELIABILITY scale — dim + italic means "less sure", used the same way
   everywhere so a deaf viewer learns to read trust at a glance:
     • cap-doubt   — a single word the recogniser was unsure of (calm, no "?")
     • cap-unsure  — a whole line it barely heard
     • cap-preroll — a line carried ahead on the song's tempo, not yet actually heard
     • cap-partial — live, still forming */
.cap-doubt { opacity: .62; font-style: italic; border-block-end: 1px dotted currentColor; }
.cap-line.cap-unsure { opacity: .82; }
.cap-line.cap-unsure .cap-text { font-style: italic; }
/* the coherence gate could not recover what was said: a quiet note, not words */
.cap-line.cap-unclear { opacity: .55; }
.cap-line.cap-unclear .cap-text { font-size: .9em; letter-spacing: .02em; }
/* Pre-rolled: the sheet carried to this line at the song's tempo before it was heard —
   shown a touch dimmer so it reads as "coming up", then firms up when actually sung. */
.cap-line.cap-preroll { opacity: .72; }
/* Non-speech sound cue ([applause], [loud sound]) — muted, italic, centred, like a TV
   closed-caption sound description. */
.cap-line.cap-event { opacity: .78; font-style: italic; text-align: center; }
.cap-line.cap-event .cap-text { letter-spacing: .02em; }
/* "Hearing you" waveform shown in place of a bare "…" while listening between lines. */
.cap-wave { display: inline-flex; align-items: flex-end; gap: 3px; height: 1em; vertical-align: middle; }
.cap-wave i { display: inline-block; width: 3px; height: 30%; border-radius: 2px;
  background: currentColor; opacity: .55; animation: cap-wave 1s ease-in-out infinite; }
.cap-wave i:nth-child(2) { animation-delay: .15s; }
.cap-wave i:nth-child(3) { animation-delay: .3s; }
.cap-wave i:nth-child(4) { animation-delay: .45s; }
.cap-wave i:nth-child(5) { animation-delay: .6s; }
@keyframes cap-wave { 0%, 100% { height: 25%; opacity: .4; } 50% { height: 95%; opacity: .8; } }
@media (prefers-reduced-motion: reduce) { .cap-wave i { animation: none; height: 55%; } }
html.dim .cap-doubt { opacity: .8; }

/* ---- clickable, or only emphasis? -----------------------------------------
   A reader should be able to tell what answers a tap without having to try it.
   Shape carries that here: anything actionable is a pill with a pointer cursor,
   a hover response and a focus ring, while anything that is only emphasis -- a
   page badge, a status chip, a heading -- is flat and square-shouldered, and
   borrows none of the border that marks a control. Colour cannot carry the
   distinction on its own, because the headings are coloured too. */
.pill, .chip, .roster-chip, #connBadge {
  border: 0;
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.07);
  cursor: default;
}
.pill {
  text-transform: uppercase;
  letter-spacing: 0.13em;
  font-size: 0.74rem;
  font-weight: 800;
  color: var(--teal);
  padding: 0.34rem 0.7rem;
}
.chip, .roster-chip, #connBadge { letter-spacing: 0.02em; color: var(--ink-2); }
/* Emphasis inside running text is weight and colour -- never a border, which
   in this interface means "you can press this". */
strong, b { font-weight: 800; color: var(--ink); }

/* A link in running text is underlined, so it is never left to colour alone.
   Navigation and anything already dressed as a button keep their own styling. */
a:not([class]) { text-decoration: underline; text-underline-offset: 0.18em; text-decoration-thickness: from-font; }
a:not([class]):hover { color: var(--ring); }

/* Controls answer to the pointer; static text does not pretend to. */
.btn, button, [role="button"], summary, label[for] { cursor: pointer; }
h1, h2, h3, h4, .eyebrow, .lede, .muted, .cap-line { cursor: default; }

/* The same rule for the remaining status labels: a state is reported, not
   offered. .narr-pill keeps a single leading rule so live / paused / stopped
   still read at a glance, without the full outline that means "press me". */
.narr-pill, .room-code, .saved-tag, .music-note {
  border-radius: 7px;
  cursor: default;
}
.narr-pill, .room-code, .saved-tag { border: 0; }
.narr-pill { border-inline-start: 3px solid currentColor; padding-inline-start: .55rem; }
.room-code, .saved-tag { background: rgba(255, 255, 255, 0.07); }

/* Per-line "Explain that" flag (reader captions). */
.cap-explain:hover { opacity: 1 !important; }

/* ===== Kahoot-style audience poll ===== */
.poll-q-text { font-size: 1.15rem; }
.poll-opts { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5rem; }
.poll-opt { display: flex; align-items: center; gap: .55rem; border: 0 !important; border-radius: 12px; padding: .85rem .8rem; min-block-size: 54px; color: #fff !important; font-weight: 800; font-size: 1rem; box-shadow: 0 2px 0 rgba(0,0,0,.18); }
.poll-opts .poll-opt:nth-child(4n+1) { background: #e21b3c; }
.poll-opts .poll-opt:nth-child(4n+2) { background: #1368ce; }
.poll-opts .poll-opt:nth-child(4n+3) { background: #d89e00; }
.poll-opts .poll-opt:nth-child(4n+4) { background: #26890c; }
.poll-opt:hover { filter: brightness(1.06); }
.poll-opt .poll-shape { font-size: 1.15rem; line-height: 1; flex: none; }
.poll-opt .poll-optlabel { position: relative; z-index: 1; }
.poll-opt.shown::before { background: rgba(255,255,255,.30) !important; }
.poll-live.voted .poll-opt:not(.mine) { opacity: .8; }
.poll-opt.mine { outline: 3px solid #fff; outline-offset: -3px; }
.poll-count { color: #fff !important; background: rgba(0,0,0,.30); border-radius: 8px; padding: .02rem .4rem; }
.poll-timer { block-size: 8px; background: rgba(0,0,0,.12); border-radius: 999px; overflow: hidden; margin: .1rem 0 .55rem; }
.poll-timer-bar { block-size: 100%; inline-size: 100%; background: linear-gradient(90deg, #26890c, #d89e00, #e21b3c); }
@keyframes pollcd { from { inline-size: 100%; } to { inline-size: 0%; } }
@media (max-width: 380px) { .poll-opts { grid-template-columns: 1fr; } }

/* Speaker session transcript — held (aside) lines struck out. */
.spk-hline { padding: .1rem 0; line-height: 1.45; }
.spk-held .spk-htext { text-decoration: line-through; opacity: .6; }
.spk-hbadge { margin-inline-start: .45rem; font-size: .68rem; font-weight: 700; color: #fff; background: #e11d48; border-radius: 999px; padding: .02rem .4rem; vertical-align: middle; white-space: nowrap; }
/* Own-voice filter: a line judged background chatter. Shown to the speaker only,
   dimmed, with its own amber badge so filtered lines are easy to scan and judge. */
.spk-offvoice .spk-htext { opacity: .5; font-style: italic; }
.spk-hbadge-off { background: #b45309; }
/* Every-10-minutes narration time marker on a spoken line. */
.spk-hts { margin-inline-start: .5rem; font-size: .7rem; font-weight: 600; opacity: .6; white-space: nowrap; }
/* A stopped project: the listener can read, but the contribution controls are
   visibly disabled (the server also refuses them). */
.proj-stopped #thumbFab, .proj-stopped #confuseFab, .proj-stopped #dmZone,
.proj-stopped #qAskForm, .proj-stopped .line-kebab { opacity: .38; pointer-events: none; }

/* Speaker's own view of a poll they launched — live tally, in the Q&A panel. */
/* The Media & polls tab (reader #mediaPane, speaker #spkPaneMP) scrolls its own
   content when it is taller than the screen, independent of page scroll. */
#mediaPane, #spkPaneMP { max-height: 78vh; max-height: 78dvh; overflow-y: auto !important; overflow-x: hidden; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }
.pollcard .spkpoll-body { margin: .35rem 0 .1rem; display: grid; gap: .3rem; }
.spkpoll-opt { position: relative; overflow: hidden; border-radius: .5rem; background: color-mix(in srgb, var(--ink) 8%, var(--surface-solid)); padding: .6rem .7rem; display: flex; align-items: center; gap: .5rem; font-size: .95rem; inline-size: 100%; border: 1px solid var(--line); text-align: start; font-family: inherit; color: var(--ink); cursor: pointer; }
.spkpoll-opt[disabled] { cursor: default; }
.spkpoll-opt:not([disabled]):hover, .spkpoll-opt:not([disabled]):focus-visible { outline: 2px solid color-mix(in srgb, var(--brand) 60%, transparent); outline-offset: -2px; }
.spkpoll-opt:not([disabled]):active { transform: scale(.99); }
.spkpoll-menu-btn { margin-inline-start: auto; border: 0; background: none; color: var(--ink-2); cursor: pointer; font-size: 1.1rem; line-height: 1; padding: 0 .3rem; }

/* Shared look for every anchored popup menu — a brand-tinted fill distinct from
   the page background, so a menu clearly reads as floating on top of it. */
.pop-menu { background: color-mix(in srgb, var(--brand) 16%, var(--surface-solid)); border: 1px solid var(--brand); box-shadow: 0 12px 30px rgba(0,0,0,.35); }

/* Signal-strength bars for the connection badge (phone → server round-trip). */
.sig-bars { display: inline-flex; align-items: flex-end; gap: 2px; block-size: 13px; }
.sig-bars i { inline-size: 3px; border-radius: 1px; background: var(--line); display: block; transition: background .3s; }
.sig-bars i:nth-child(1) { block-size: 5px; }
.sig-bars i:nth-child(2) { block-size: 8px; }
.sig-bars i:nth-child(3) { block-size: 10px; }
.sig-bars i:nth-child(4) { block-size: 13px; }
.spkpoll-menu { margin-top: .4rem; padding: .35rem; border-radius: 10px; display: none; }
.spkpoll-bar { position: absolute; inset-block: 0; inset-inline-start: 0; inline-size: 0; background: linear-gradient(90deg, rgba(38,137,12,.28), rgba(38,137,12,.16)); transition: inline-size .4s ease; }
.spkpoll-lbl { position: relative; flex: 1 1 auto; min-inline-size: 0; }
.spkpoll-n { position: relative; font-weight: 700; font-variant-numeric: tabular-nums; opacity: .85; white-space: nowrap; }
.spkpoll-foot { font-size: .74rem; opacity: .7; margin-top: .15rem; }
.spkpoll-hint { font-size: .74rem; margin: .1rem 0 .4rem; color: var(--brand); }
.spkpoll-mine { box-shadow: inset 0 0 0 2px var(--brand); }
.spkpoll-confirm { margin: .5rem 0 .1rem; padding: .5rem .7rem; border-radius: .6rem; background: color-mix(in srgb, var(--brand) 16%, transparent); border: 1px solid var(--brand); color: var(--ink); font-weight: 700; font-size: .88rem; }
.spkpoll-mine .spkpoll-lbl { font-weight: 700; }
.spkpoll-closed .spkpoll-bar { background: linear-gradient(90deg, rgba(38,137,12,.45), rgba(38,137,12,.28)); }

/* ============================================================================
   CONTEMPORARY REFRESH (v2) — techy but low-key, smart, restrained.
   Layered over the base styles (later rules win) so the original look stays a
   git restore point. Dials back the rainbow/glow, tightens depth to hairlines
   and soft shadows, adds monospace numerics, and gives menus/popups/modals a
   subtle entrance. All motion is reduced-motion aware.
   ============================================================================ */
:root {
  /* A cooler, more neutral slate base (was a saturated navy) — reads more
     contemporary/engineered. These tokens are referenced by the speaker/listener
     inline styles, so shifting them re-tones those pages too. */
  --bg: #05070d;
  --bg-2: #0a0f1c;
  --surface: rgba(150, 180, 230, 0.05);
  --surface-solid: #0e1422;
  --ink: #eef3fb;
  --ink-2: #9aa8c4;
  /* Restrained, single-accent-leaning palette (cyan → indigo, no pink bloom). */
  --brand: #4ee1ff;
  --ring: #7de9ff;
  --line: rgba(150, 180, 230, 0.13);          /* crisp hairline */
  --line-strong: rgba(150, 180, 230, 0.24);
  --grad: linear-gradient(120deg, #38dcff, #8b9bff 72%);
  --grad-warm: linear-gradient(120deg, #2dd4bf, #7dd3fc);
  /* Softer, tighter depth — a smart panel floats, it doesn't shout. */
  --shadow: 0 14px 38px rgba(0, 0, 0, 0.42);
  --shadow-sm: 0 4px 16px rgba(0, 0, 0, 0.30);
  --glow: 0 0 0 1px rgba(78, 225, 255, 0.16);
  --radius: 14px;
  --font: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;
  --dur: 0.2s;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* Contemporary UI type: Inter, a touch tighter. The engineered feel comes from the
   monospace numerics (set further down), not from a loud display face. */
body { font-family: var(--font); letter-spacing: -0.006em; }
h1, h2, h3, .brand { letter-spacing: -0.025em; }

/* Calm the aurora: dimmer and slower, more atmosphere than light show. */
body::before { opacity: 0.42; animation-duration: 44s; filter: blur(28px); }
/* A faint engineering grid behind everything — the low-key "techy" texture. Kept
   under the content and very light, with the existing vignette on top. */
body::after {
  background:
    radial-gradient(120% 80% at 50% -10%, transparent 58%, var(--bg) 100%),
    linear-gradient(rgba(148, 176, 224, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(148, 176, 224, 0.045) 1px, transparent 1px);
  background-size: 100% 100%, 46px 46px, 46px 46px;
}

/* Gradient text: keep the sheen, slow it right down so it reads as premium, not busy. */
.grad-text { animation-duration: 18s; }

/* Precise, low-key focus ring (box-shadow doesn't fight inline borders). */
:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
input:focus, textarea:focus, select:focus, [contenteditable]:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(78, 225, 255, 0.16);
  border-radius: 10px;
}
input, textarea, select { transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease); }

/* Monospace, tabular numerics for the techy details: timestamps, chips, meters,
   signal bars, the connection readout — small, precise, engineered-feeling. */
.cap-dm-time, .cap-media-time, .cap-poll-time, .cap-typed-time, .spk-hts,
.chip, .sig-bars, .qtime, .cap-time, .sys-time, .sent-by {
  font-family: var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
}

/* Buttons — restrained. Primary is a calm cyan→indigo, not a three-stop rainbow. */
.btn { transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), background var(--dur) var(--ease), border-color var(--dur) var(--ease), filter var(--dur) var(--ease); }
.btn-primary {
  background: linear-gradient(135deg, #0ea6c9, #5b62e6);
  box-shadow: var(--shadow-sm); text-shadow: none; background-size: 140% auto;
}
.btn-primary:hover { filter: brightness(1.07); transform: translateY(-1px); box-shadow: 0 10px 26px rgba(91, 98, 230, 0.30); }
.btn-ghost:hover { border-color: color-mix(in srgb, var(--brand) 55%, var(--line)); background: color-mix(in srgb, var(--brand) 8%, var(--surface)); box-shadow: none; }

/* Cards — hairline lift instead of a colored glow. */
.card { box-shadow: var(--shadow-sm); }
.card:hover { transform: translateY(-3px); border-color: var(--line-strong); box-shadow: var(--shadow); }

/* Nav links: quiet, smart hover. */
nav.main a:hover { color: var(--ink); background: color-mix(in srgb, var(--brand) 10%, transparent); }

/* Speaker view-tabs: solid tinted pill instead of the rainbow gradient. */
.spk-tab.on { background: color-mix(in srgb, var(--brand) 20%, var(--surface-solid)); color: var(--ink); }

/* ---- Motion: menus, popups and modals get a subtle, quick entrance ---- */
@keyframes shooraPop { from { opacity: 0; transform: translateY(5px) scale(0.985); } to { opacity: 1; transform: none; } }
@keyframes shooraFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes shooraRise { from { opacity: 0; transform: translateY(10px) scale(0.98); } to { opacity: 1; transform: none; } }

.line-menu, .ctl-menu, #spkFilterMenu, #addNarrMenu, .pinned-res-pop, .spkpoll-menu, .qMenu {
  animation: shooraPop var(--dur) var(--ease); transform-origin: top center;
}
.line-compose-ov { animation: shooraFade var(--dur) ease; }
.line-compose { animation: shooraRise 0.24s var(--ease); }

/* Interactive timeline items ease their hover/state changes. */
.cap-poll-pill, .cap-media, .cap-typed, .cap-react, .line-kebab, .cap-cmt, .cap-dm, .spk-dm {
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.line-kebab { border-radius: 8px; }
.line-kebab:hover { background: color-mix(in srgb, var(--brand) 12%, transparent); }

/* Toast: smooth fade (JS toggles opacity; the transition makes it glide). */
#shooraToast { transition: opacity 0.28s var(--ease), transform 0.28s var(--ease); }

/* Honour reduced motion: no entrances, no drift, no sheen. */
@media (prefers-reduced-motion: reduce) {
  body::before { animation: none; }
  .grad-text { animation: none; }
  .line-menu, .ctl-menu, #spkFilterMenu, #addNarrMenu, .pinned-res-pop, .spkpoll-menu,
  .qMenu, .line-compose-ov, .line-compose { animation: none; }
  .btn, .card, .cap-poll-pill, .cap-media, .cap-typed, .cap-react, .line-kebab { transition: none; }
}

/* Pinned post: the "first shared with listeners" sub-line under the welcome text. */
.pinned-sub { font-size: 0.72rem; color: var(--ink-2); opacity: 0.9; margin-top: 0.15rem; line-height: 1.3; }
.pinned-date { font-family: var(--mono); font-variant-numeric: tabular-nums; color: var(--ink); }

/* Collapsible pinned post: chevron toggles; collapsed by default (never persisted). */
.pinned-toggle {
  background: transparent; border: 0; color: var(--ink-2); cursor: pointer;
  font-size: 0.8rem; line-height: 1; padding: 0.25rem 0.4rem; margin-inline-start: 0.15rem;
  border-radius: 8px; flex: 0 0 auto; align-self: center;
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.pinned-toggle:hover { background: color-mix(in srgb, var(--brand) 12%, transparent); color: var(--ink); }
.pinned-bar:not(.collapsed) .pinned-toggle { transform: rotate(90deg); }
.pinned-bar.collapsed .pinned-sub,
.pinned-bar.collapsed .pinned-poll { display: none; }
/* Collapsed: 📌 + text + chevron on ONE line; the text truncates to fit. */
.pinned-bar.collapsed .pinned-main { flex-wrap: nowrap; align-items: center; }
.pinned-bar.collapsed .pinned-text {
  flex: 1 1 auto; min-inline-size: 0;
  display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  -webkit-line-clamp: none;
}
.pinned-toggle { flex: 0 0 auto; }
@media (prefers-reduced-motion: reduce) { .pinned-toggle { transition: none; } }

/* Narration search (speaker): the bar over the timeline + match highlighting. */
.spk-search-bar { display: flex; align-items: center; gap: 0.4rem; margin-bottom: 0.5rem; padding: 0.35rem 0.5rem; border: 1px solid var(--line-strong); border-radius: 12px; background: color-mix(in srgb, var(--brand) 8%, var(--surface-solid)); }
.spk-search-bar[hidden] { display: none; }   /* display:flex above would beat [hidden] */
.spk-search-bar input { flex: 1 1 auto; min-inline-size: 0; border: 0; background: transparent; color: var(--ink); font: inherit; font-size: 0.9rem; outline: none; }
.spk-search-bar .btn { padding: 0.3rem 0.5rem; font-size: 0.9rem; }
.spk-search-count { font-family: var(--mono); font-variant-numeric: tabular-nums; font-size: 0.75rem; color: var(--ink-2); flex: 0 0 auto; white-space: nowrap; }
.line-row.search-hit { background: color-mix(in srgb, var(--amber) 20%, transparent); border-radius: 8px; }
.line-row.search-current { box-shadow: inset 0 0 0 2px var(--brand); background: color-mix(in srgb, var(--brand) 16%, transparent); border-radius: 8px; }

/* When the pinned post is collapsed, hide its right-side icons (📶 reception meter
   and ⋯ resources kebab) — they show only once it is expanded. */
.pinned-bar.collapsed .pinned-right,
.pinned-bar.collapsed .pinned-res-wrap { display: none; }

/* Much thinner (fainter) hairline border on the narration/reading box. */
#readPaneNarr { border-color: color-mix(in srgb, var(--line) 40%, transparent);
  /* The default .panel padding (~1.5rem) left a big gap between the Read-along row
     and the pinned post at the top of the box; tighten it right down. */
  padding: .5rem .7rem; }

/* Speaker panel: tighter padding + hairline border so the narration/pinned/compose
   block sits much closer to the top of the screen with a much thinner frame. */
#paneSpeaker { padding: .5rem .7rem; border-color: color-mix(in srgb, var(--line) 35%, transparent); }

/* Pinned "speaker CV" link. */
.pinned-speaker-link { color: var(--brand); text-decoration: none; font-weight: 600; }
.pinned-speaker-link:hover { text-decoration: underline; }

/* Pinned action links row (connection · about · speaker CV). */
.pinned-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.pinned-actsep { color: var(--ink-2); opacity: .5; }
/* Collapse chevron always at the far right of the pinned header. */
.pinned-toggle { margin-inline-start: auto; }

/* Automated narration start/stop system line — centered, full width. */
.cap-sys { align-self: stretch; text-align: center; margin: .35rem 0; padding: .38rem .7rem;
  border-radius: 10px; font-size: .82rem; font-weight: 700; color: var(--ink);
  background: color-mix(in srgb, var(--brand) 12%, var(--surface-solid));
  border: 1px solid color-mix(in srgb, var(--brand) 30%, var(--line)); }
.cap-sys-stop { color: var(--ink-2);
  background: color-mix(in srgb, #94a3b8 14%, var(--surface-solid));
  border-color: color-mix(in srgb, #94a3b8 32%, var(--line)); }

/* Follow-mode picker: the per-option explanation under the buttons. */
.follow-hint { flex-basis: 100%; font-size: .72rem; color: var(--ink-2); line-height: 1.35; margin-top: .1rem; }

/* ---- On-demand narration summary: floating "+" menu + the Summary line ---- */
.summ-fab { position: fixed; inset-inline-end: 16px; inset-block-end: 88px; z-index: 70;
  inline-size: 46px; block-size: 46px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--brand); color: #04101c; font-size: 1.7rem; line-height: 1; font-weight: 400;
  display: flex; align-items: center; justify-content: center; box-shadow: 0 6px 20px rgba(0,0,0,.35);
  transition: transform .12s ease; }
.summ-fab:active { transform: scale(.92); }
.summ-fab[aria-expanded="true"] { transform: rotate(45deg); }
.summ-fab.summ-fab-custom { font-size: 1.6rem; font-weight: 700; }
.summ-fab.summ-fab-custom[aria-expanded="true"] { transform: none; }
/* Mounted inside an existing control column (e.g. the listener's tools stack): sit in
   flow rather than floating over other buttons. */
.summ-fab-inline { position: static; inset: auto; inline-size: 52px; block-size: 52px; font-size: 1.9rem; }
.summ-menu { position: fixed; left: 0; top: 0; z-index: 71;
  /* Tinted like the 📎 menus so it stands apart from the app background. */
  background: color-mix(in srgb, var(--brand) 16%, var(--surface-solid));
  border: 1px solid color-mix(in srgb, var(--brand) 45%, var(--line)); border-radius: 14px;
  box-shadow: 0 12px 34px rgba(0,0,0,.45); padding: .3rem; min-inline-size: 210px;
  display: flex; flex-direction: column; gap: .1rem; }
.summ-menu[hidden] { display: none; }
.summ-menu .summ-mhead { padding: .45rem .7rem .25rem; font-size: .72rem; color: var(--ink-2);
  font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.summ-menu button { display: flex; align-items: center; gap: .55rem; inline-size: 100%;
  text-align: start; padding: .58rem .7rem; border: 0; background: transparent; color: var(--ink);
  font: inherit; font-size: .92rem; border-radius: 9px; cursor: pointer; }
.summ-menu button:hover, .summ-menu button:focus-visible { background: rgba(127,127,127,.14); outline: none; }
.summ-menu .summ-back { color: var(--ink-2); font-size: .82rem; }

.cap-summary { border: 1px solid var(--brand); border-radius: 14px; padding: .55rem .72rem;
  background: color-mix(in srgb, var(--brand) 10%, transparent); margin: .25rem 0; }
.cap-summary .summary-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: .35rem;
  font-size: .78rem; font-weight: 700; color: var(--brand); margin-block-end: .32rem; }
.cap-summary .summary-when { font-weight: 400; color: var(--ink-2); font-size: .72rem; }
.cap-summary .summary-body { white-space: pre-wrap; color: var(--ink); line-height: 1.5; }

/* The big "Start narration" button is superseded by the 🎙 voice icon in the type row
   (same wizard, incl. Live/Dry). Hidden from view; the #startBtn element stays in the DOM
   because its .hidden state and click logic drive the voice icon, Pause/Stop and resume. */
#startWrap { display: none !important; }

/* Voice icon in its running state: a red Stop/Pause control (vs the idle 🎙 start icon). */
#spkVoiceBtn.voice-stop { background: #f43f5e; color: #fff; border-color: #f43f5e; border-radius: 10px; font-size: 1.05rem; }
#spkVoiceBtn.voice-stop:hover { background: #e11d48; }

/* Dry-run (rehearsal) narration on the speaker screen: shown to the speaker only and
   never broadcast, so it renders amber with a 🕶 marker to distinguish it from live text. */
.spk-hline.spk-dry .spk-htext { color: #f59e0b; }
.spk-hline.spk-dry .spk-htext::before { content: "🕶 "; opacity: .75; }

/* Collapsible "Narration status change" group — a run of start/stop notes folded into
   one line (collapsed by default). Muted, like the individual .cap-sys notes. */
.narr-status-group { margin: .15rem 0; }
.narr-status-head { display: inline-flex; align-items: center; gap: .35rem; background: none; border: 0;
  color: var(--ink-2); font: inherit; font-size: .82rem; cursor: pointer; padding: .15rem 0; opacity: .85; }
.narr-status-head:hover { opacity: 1; }
.narr-status-body { display: flex; flex-direction: column; gap: .1rem; margin: .25rem 0 .3rem .4rem;
  padding: .5rem .65rem; border-radius: 12px; border: 1px solid var(--line);
  background: var(--surface-solid);                                   /* fallback */
  background: color-mix(in srgb, var(--ink) 7%, var(--surface));      /* distinct from the app bg */
  max-block-size: min(50vh, 360px); overflow-y: auto; overscroll-behavior: contain;
  box-shadow: inset 0 1px 6px rgba(0,0,0,.15); }
/* The base rule above (a class) otherwise overrides the UA [hidden] rule, so collapsing
   had no visual effect — this makes the collapsed (hidden) state actually hide. */
.narr-status-body[hidden] { display: none !important; }

/* Speaker ⋯ More options: the same dropdown as the floating "+" menu — anchored to the
   ⋯ button, tinted, compact rows — instead of a centred dialog of pill buttons. */
#moreModal { background:transparent !important; -webkit-backdrop-filter:none !important; backdrop-filter:none !important; padding:0 !important; overflow:visible !important; }
#moreModal > .panel {
  position:fixed !important; margin:0 !important; inline-size:auto !important; min-inline-size:230px; max-inline-size:min(92vw, 300px) !important;
  background:color-mix(in srgb, var(--brand) 16%, var(--surface-solid)) !important;
  border:1px solid color-mix(in srgb, var(--brand) 45%, var(--line)) !important; border-radius:14px !important;
  box-shadow:0 12px 34px rgba(0,0,0,.45) !important; padding:.3rem !important;
}
#moreModal #moreClose { display:none; }
#moreModal .eyebrow { margin:0 !important; padding:.45rem .7rem .25rem; font-size:.72rem; color:var(--ink-2) !important; letter-spacing:.04em; }
#moreModal .more-item {
  display:flex !important; align-items:center; gap:.55rem; inline-size:100%;
  padding:.58rem .7rem !important; margin:0; border:0 !important; border-radius:9px !important;
  background:transparent !important; box-shadow:none !important; font:inherit; font-size:.92rem; font-weight:400;
  text-align:start; color:var(--ink) !important; text-decoration:none; justify-content:flex-start !important; min-block-size:0 !important;
}
#moreModal .more-item:hover, #moreModal .more-item:focus-visible { background:rgba(127,127,127,.14) !important; outline:none; }
#moreModal .more-all-projects {
  display:flex; align-items:center; gap:.55rem; margin-top:.2rem; padding:.58rem .7rem; border-top:1px solid color-mix(in srgb, var(--brand) 30%, var(--line));
  border-radius:0 0 9px 9px; color:var(--brand); font-size:.92rem; font-weight:600; text-decoration:none;
}
#moreModal .more-all-projects:hover { background:rgba(127,127,127,.14); }

/* The Pause ▾ / Stop ▾ pair under the type box is redundant with the 🎙/⏹ icon's menu.
   The buttons stay in the page (their handlers drive run state) but are never shown. */
#liveControls { display:none !important; }

/* 👤 account menu — the same panel as the "+" menu (.summ-menu). */
.acct-menu { flex-direction: column; gap: .1rem; padding: .3rem; min-inline-size: 230px;
  background: color-mix(in srgb, var(--brand) 16%, var(--surface-solid));
  border: 1px solid color-mix(in srgb, var(--brand) 45%, var(--line)); border-radius: 14px;
  box-shadow: 0 12px 34px rgba(0,0,0,.45); text-align: start; }
.acct-menu .acct-head { padding: .5rem .7rem .15rem; font-size: .8rem; color: var(--ink-2); display: flex; gap: .45rem; align-items: baseline; }
.acct-menu .acct-email { word-break: break-all; font-weight: 600; color: var(--ink); }
.acct-menu .acct-nick { padding: .1rem .7rem .4rem; font-size: .8rem; color: var(--ink-2); }
.acct-menu .acct-nick-row { display: flex; align-items: center; gap: .45rem; }
.acct-menu .acct-nick-val { word-break: break-all; }
.acct-menu .acct-nick-edit { border: 0; background: transparent; color: var(--brand); cursor: pointer; font-size: .85rem; padding: .1rem .25rem; border-radius: 6px; }
.acct-menu .acct-nick-edit:hover { background: rgba(127,127,127,.14); }
.acct-menu .acct-sep { block-size: 1px; background: color-mix(in srgb, var(--brand) 30%, var(--line)); margin: .15rem .4rem; }
.acct-menu .acct-mi { display: flex; align-items: center; gap: .55rem; inline-size: 100%; box-sizing: border-box;
  text-align: start; padding: .58rem .7rem; border: 0; background: transparent; color: var(--ink);
  font: inherit; font-size: .92rem; border-radius: 9px; cursor: pointer; text-decoration: none; }
.acct-menu .acct-mi:hover, .acct-menu .acct-mi:focus-visible { background: rgba(127,127,127,.14); outline: none; }
.acct-menu-guest { padding: .7rem; min-inline-size: 240px; }

/* ---- Two screens: narration / Active interaction (listener page) ---------------- */
.viewmode-wrap { position: relative; display: inline-flex; flex: none; }
.viewmode-btn { position: relative; display: inline-flex; align-items: center; gap: .15rem; padding: .3rem .5rem; border-radius: 999px; border: 1px solid var(--line); background: var(--surface-solid); color: var(--ink); cursor: pointer; font: inherit; font-size: 1rem; line-height: 1; }
.viewmode-btn:hover, .viewmode-btn[aria-expanded="true"] { border-color: var(--brand); }
.viewmode-caret { font-size: .7rem; opacity: .7; }
.viewmode-dot { position: absolute; inset-block-start: -2px; inset-inline-end: -2px; inline-size: 10px; block-size: 10px; border-radius: 50%; background: #ef4444; border: 2px solid var(--surface-solid); }
.viewmode-menu { position: absolute; inset-block-start: calc(100% + 6px); inset-inline-start: 0; z-index: 80; display: flex; flex-direction: column; gap: .15rem; min-inline-size: 13rem; padding: .35rem; border-radius: 12px; background: var(--surface-solid); border: 1px solid var(--line); box-shadow: 0 10px 30px rgba(0,0,0,.25); }
.viewmode-menu[hidden] { display: none; }
.viewmode-item { display: flex; align-items: center; gap: .5rem; padding: .55rem .7rem; border: 0; border-radius: 8px; background: none; color: var(--ink); font: inherit; font-size: .95rem; text-align: start; cursor: pointer; }
.viewmode-item:hover { background: color-mix(in srgb, var(--brand) 12%, transparent); }
.viewmode-item[aria-checked="true"] { font-weight: 700; background: color-mix(in srgb, var(--brand) 18%, transparent); }

/* The chat itself: a WhatsApp-like thread (WhatsApp's dark palette, as Shoora is dark) —
   our lines on the end side in green, others on the start side with their name, the
   speaker's marked in amber. */
.ichat-box { display: flex; flex-direction: column; gap: .35rem; padding: .6rem .5rem; margin: 0 -.25rem; border-radius: 12px; min-block-size: 100%; flex: 0 0 auto;   /* grows with its messages (the list scrolls, not the box) */
 
  background-color: #0b141a; background-image: radial-gradient(rgba(255,255,255,.045) 1px, transparent 1px); background-size: 14px 14px; }
.ichat-box[hidden] { display: none; }
.ichat-empty { margin: auto; max-inline-size: 22rem; text-align: center; font-size: .88rem; color: #aebac1; background: #182229; padding: .5rem .8rem; border-radius: 8px; }
.ichat-msg { position: relative; max-inline-size: min(80%, 34rem); align-self: flex-start; padding: .35rem .6rem .25rem; border-radius: 10px; border-start-start-radius: 2px; background: #202c33; color: #e9edef; box-shadow: 0 1px 1px rgba(0,0,0,.3); font-size: .95rem; line-height: 1.35; }
.ichat-mine { align-self: flex-end; background: #005c4b; border-start-start-radius: 10px; border-start-end-radius: 2px; }
.ichat-spk { background: #3a2a14; border: 1px solid #7c4a12; }
.ichat-who { font-size: .78rem; font-weight: 700; color: #53bdeb; margin-block-end: .1rem; }
.ichat-spk .ichat-who { color: #f5b35c; }
.ichat-text { white-space: pre-wrap; overflow-wrap: anywhere; }
.ichat-time { font-size: .68rem; color: #aebac1; text-align: end; margin-block-start: .1rem; }
.ichat-pending { opacity: .65; }

/* A listener's photo / PDF on a private message or a chat line. */
.msg-att-img { display: block; margin-block: .35rem .15rem; }
.msg-att-img img { display: block; max-inline-size: min(260px, 100%); max-block-size: 320px; border-radius: 8px; object-fit: cover; }
.msg-att-pdf { display: inline-flex; align-items: center; gap: .35rem; margin-block: .35rem .15rem; padding: .45rem .7rem; border-radius: 8px; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.14); color: inherit; font-weight: 600; font-size: .88rem; text-decoration: none; overflow-wrap: anywhere; }
.msg-att-pdf:hover { background: rgba(255,255,255,.14); }
.cap-dm .msg-att-img, .cap-dm .msg-att-pdf { flex-basis: 100%; }
/* A follow-on line from the same sender (WhatsApp-style group): closer, no name, no pointed corner. */
.ichat-msg.ichat-cont { margin-block-start: -.2rem; border-start-start-radius: 10px; }
.ichat-mine.ichat-cont { border-start-end-radius: 10px; }
.ichat-msg:not(.ichat-cont) { margin-block-start: .25rem; }

/* Speaker page: the project name with the narration / Active interaction switch beside it,
   in a fixed row above the timeline (so the switch never scrolls away). */
.spk-titlerow { flex: 0 0 auto; display: flex; align-items: center; gap: .5rem; margin: 0 0 .4rem; min-block-size: 2rem; }
.spk-titlerow #spkNarrTitle { min-inline-size: 0; }
.spk-titlerow .viewmode-wrap { margin-inline-start: auto; }
.viewmode-menu-end { inset-inline-start: auto; inset-inline-end: 0; }

/* Who is speaking: the voice's name on a line in the speaker's transcript (tap to name). */
.spk-voice { flex: 0 0 auto; margin-inline-end: .35rem; padding: .05rem .45rem; border-radius: 999px; border: 1px solid currentColor; background: transparent; font: inherit; font-size: .72rem; font-weight: 800; cursor: pointer; line-height: 1.5; }
.spk-voice:hover { background: color-mix(in srgb, currentColor 18%, transparent); }
.narr-sub { margin-inline-start: .4rem; font-size: .78rem; opacity: .85; }

/* The message row (listener and speaker): the box grows with the text, so its controls sit
   at the bottom — and they are all one height, so their icons share a line with the box's
   own text instead of each sitting a few pixels off. */
#dmForm, #typedForm { align-items: flex-end; }
#dmForm > *, #typedForm > * { block-size: 43px; }
#dmForm > #dmInput, #typedForm > #typedInput { block-size: auto; min-block-size: 43px; }
#dmForm > * :where(button), #dmForm > button, #typedForm > * :where(button), #typedForm > button {
  block-size: 43px; min-inline-size: 43px; padding-block: 0; display: inline-flex; align-items: center; justify-content: center; }
/* …except the round Send on the speaker's row, which is a circle by design. */
#typedForm > button[type="submit"] { block-size: 38px; min-inline-size: 38px; align-self: center; }

/* Competition page — check-mark grid */
.comp-grid td{ text-align:center; vertical-align:middle }
.comp-grid thead th:not(:first-child){ text-align:center }
.comp-grid .comp-eg{ margin-inline:auto }
.comp-grid tbody th[scope=row]{ vertical-align:middle }
.cmk{ display:inline-flex; align-items:center; justify-content:center; width:1.7rem; height:1.7rem; border-radius:50%; font-weight:800; font-size:.95rem; line-height:1 }
.cmk-y{ background:rgba(52,211,153,.18); color:#34d399 }
.cmk-p{ background:rgba(251,191,36,.16); color:var(--amber) }
.cmk-n{ background:rgba(148,163,184,.10); color:var(--ink-2); opacity:.55 }
.comp-us .cmk-y{ background:#34d399; color:#04140d; box-shadow:0 0 0 4px rgba(52,211,153,.18) }
.cmk-note{ display:block; margin-top:.35rem; font-size:.74rem; font-weight:500; color:var(--ink-2); line-height:1.3 }
.comp-us .cmk-note{ color:var(--ink) }
.cmk-cost{ display:inline-block; padding:.25rem .6rem; border-radius:999px; font-size:.8rem; font-weight:600; color:var(--ink-2); background:rgba(148,163,184,.10) }
.cmk-cost.win{ color:#04140d; background:#34d399 }

/* ---- Blog: tweet-sized posts ---- */
.blog-filter { display: flex; flex-wrap: wrap; gap: .5rem; justify-content: center; margin: 0 0 1.4rem; }
.blog-filter a { padding: .4rem .9rem; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--ink-2); text-decoration: none; font-size: .88rem; font-weight: 600; }
.blog-filter a[aria-current="true"], .blog-filter a:hover { color: var(--ink); border-color: var(--brand); }
.blog-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); gap: 1rem; }
.blog-card { display: flex; flex-direction: column; gap: .7rem; padding: 1.3rem; }
.blog-meta { display: flex; justify-content: space-between; align-items: center; gap: .5rem; font-size: .78rem; color: var(--ink-2); }
.blog-tag { padding: .15rem .55rem; border: 1px solid var(--line); border-radius: 999px; }
.blog-title { font-size: 1.12rem; line-height: 1.3; margin: 0; }
.blog-title a { color: var(--ink); text-decoration: none; }
.blog-title a:hover { color: var(--brand); }
.blog-tweet { margin: 0; color: var(--ink); line-height: 1.55; white-space: pre-line; flex: 1 1 auto; }
.blog-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem .9rem; font-size: .82rem; }
.blog-x { padding: .38rem .85rem; font-size: .82rem; }
.blog-src, .blog-other { color: var(--ink-2); text-decoration: none; overflow-wrap: anywhere; }
.blog-src:hover, .blog-other:hover { color: var(--brand); }
.blog-other { margin-inline-start: auto; }
.blog-cta { display: flex; flex-wrap: wrap; gap: .8rem; align-items: center; justify-content: space-between; margin-top: 1rem; padding: 1rem 1.2rem; }
.blog-pager { display: flex; justify-content: space-between; gap: 1rem; margin-top: 1.2rem; font-size: .88rem; }
.blog-pager a { color: var(--ink-2); text-decoration: none; }
.blog-pager a:hover { color: var(--brand); }

/* About ▸ Case studies: a sub-group inside the About dropdown, drawn as a group header and
   an indented item (the menu has no nested flyouts). Same on the mobile panel. */
nav.main .navdrop-menu a.navsub-item { padding-inline-start: 1.7rem; }
@media (max-width: 900px) { .navdrop-menu .navsub-head .navcaret { display: none; } }

/* Homepage theatre film (2026-10-15). */
.home-film .film-box{position:relative}
.home-film video{display:block;width:100%;aspect-ratio:16/9;border-radius:20px;background:#000;border:1px solid var(--line);box-shadow:var(--shadow)}
.home-film figcaption{margin-top:.7rem;font-size:.9rem;color:var(--ink-2)}
.home-film .film-sound{position:absolute;top:14px;inset-inline-end:14px;padding:.55rem 1rem;border:0;border-radius:999px;background:rgba(5,7,13,.72);color:#fff;font:600 .9rem/1 inherit;cursor:pointer;backdrop-filter:blur(4px)}
.home-film .film-sound:hover{background:rgba(5,7,13,.9)}
.home-film .film-sound[hidden]{display:none}
.home-film{padding-block:2rem 1rem}

/* shoora.me/videos (2026-10-16) */
.vid-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:22px;margin-top:1.5rem}
.vid-card{display:block;color:inherit;text-decoration:none;background:var(--surface-solid);border:1px solid var(--line);border-radius:16px;overflow:hidden;transition:border-color .2s}
.vid-card:hover{border-color:var(--brand)}
.vid-card img{display:block;width:100%;aspect-ratio:16/9;object-fit:cover;background:#000}
.vid-meta{padding:12px 14px 14px;text-align:start}
.vid-meta b{display:block;font-size:1.02rem;color:var(--ink)}
.vid-meta span{display:block;color:var(--ink-2);font-size:.88rem;margin-top:4px;line-height:1.45}
.vid-meta code{display:block;color:var(--brand);font-size:.8rem;margin-top:6px;text-align:start}
