* { box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; margin: 0; background: #f6f5f3; color: #1c1c1a; }
.wrap { max-width: 640px; margin: 0 auto; padding: 16px; }
h1 { font-size: 20px; font-weight: 600; }
h2 { font-size: 15px; font-weight: 600; color: #555; text-transform: uppercase; letter-spacing: .03em; }
.section { margin-bottom: 6px; }
.section-header { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; background: none; border: none; padding: 8px 0; font: inherit; font-size: 15px; font-weight: 600; color: #555; text-transform: uppercase; letter-spacing: .03em; cursor: pointer; }
.section-header .chevron { display: inline-block; font-size: 11px; transition: transform .15s ease; }
.section.collapsed .chevron { transform: rotate(-90deg); }
.section.collapsed .section-body { display: none; }
button { font: inherit; padding: 10px 16px; border-radius: 8px; border: 1px solid #ccc; background: #fff; cursor: pointer; }
button.primary { background: #1c1c1a; color: #fff; border-color: #1c1c1a; }
button:disabled { opacity: .5; cursor: not-allowed; }
.type-btn { padding: 6px 14px; font-size: 13px; border-radius: 999px; }
.type-btn.active { background: #1c1c1a; color: #fff; border-color: #1c1c1a; }
a.button-like { font: inherit; padding: 10px 16px; border-radius: 8px; border: 1px solid #ccc; background: #fff; text-decoration: none; color: inherit; display: inline-block; }
textarea, input { font: inherit; width: 100%; padding: 10px; border-radius: 8px; border: 1px solid #ccc; }
select { font: inherit; padding: 10px 12px; border-radius: 8px; border: 1px solid #ccc; background: #fff; cursor: pointer; }
.card { background: #fff; border: 1px solid #e4e2dd; border-radius: 12px; padding: 14px 16px; margin-bottom: 10px; }
.row { display: flex; gap: 8px; align-items: center; justify-content: space-between; }
.muted { color: #888; font-size: 13px; }
.flagged { border-left: 3px solid #d85a30; }
.pill { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; background: #eee; }
.pill.status-live { background: #dff5e6; color: #1a6b3c; }
.pill.status-pending { background: #fdf3d9; color: #8a6d1a; }
.pill.status-rejected { background: #fbe1df; color: #a23b32; }
.upvote { border: none; background: #f0efe9; border-radius: 8px; padding: 6px 10px; font-weight: 600; white-space: nowrap; flex-shrink: 0; }
/* A non-interactive vote count — used for "this is your own contribution,
   you can't upvote it" in the contributor view, and for every count in the
   broadcast view, since nothing there is clickable. Sized and shaped to
   match .upvote so it doesn't look like a different, oddly-proportioned
   component sitting next to the real buttons — that mismatch, plus the
   .pill class it used to borrow being nearly invisible against the dark
   broadcast background and prone to wrapping under a long question, were
   the three UI bugs reported together. white-space: nowrap and flex-shrink:
   0 mean the row's flex layout squeezes the question text instead of this
   badge, which is what was happening before. */
.vote-badge { display: inline-block; background: #f0efe9; color: #1c1c1a; border-radius: 8px; padding: 6px 10px; font-weight: 600; white-space: nowrap; flex-shrink: 0; }
.broadcast-body { background: #16161a; color: #f5f5f0; height: 100vh; overflow: hidden; margin: 0; }
.broadcast-body .card { background: #23232a; border-color: #34343c; color: #f5f5f0; }
.broadcast-body .muted { color: #9a9aa2; }
.broadcast-body .vote-badge { background: #34343c; color: #f5f5f0; }

/* Full-screen, no-scroll shell: a fixed sidebar plus a main area that fills
   whatever's left. Sized entirely in vw/vh/clamp() rather than breakpoints
   for specific resolutions — Full HD and QHD are both 16:9, so this is a
   pure scaling problem, and a fluid layout scales correctly between (and
   beyond) both without needing to special-case either one. A 2vh/2vw outer
   inset guards against displays or projectors that crop slightly at the
   true edge. */
.broadcast-shell { display: grid; grid-template-columns: minmax(200px, 18vw) 1fr; gap: 2vw; height: 100vh; width: 100vw; padding: 2vh 2vw; }

.sidebar { display: flex; flex-direction: column; align-items: flex-start; gap: 2vh; min-height: 0; overflow: hidden; }
/* A fixed 2:1 slot regardless of what image actually fills it — object-fit:
   contain means a source that isn't exactly 2:1 (a square SVG mark, say)
   still fits without being stretched or cropped, just letterboxed within
   the same landscape shape rather than distorting it. */
.sidebar .logo { width: 100%; aspect-ratio: 2 / 1; object-fit: contain; flex-shrink: 0; }
.sidebar h1 { font-size: clamp(1.1rem, 1.8vw, 2rem); line-height: 1.25; margin: 0; flex-shrink: 0; }
.qr-block { margin-top: auto; background: #fff; border-radius: 12px; padding: 1.4vw; text-align: center; flex-shrink: 0; width: 100%; }
.qr-block img { width: 100%; height: auto; display: block; }
.qr-block .qr-caption { margin-top: 0.8vh; font-size: clamp(11px, 1vw, 15px); color: #1c1c1a; font-weight: 600; }

.main-area { min-width: 0; min-height: 0; overflow: hidden; }

/* Dashboard mode: all three regions visible at once. Questions and poll
   share the top row, mood spans the full width underneath. */
.main-area.dashboard-grid { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 1.5vw; height: 100%; }
.region-questions { grid-column: 1; grid-row: 1; }
.region-poll { grid-column: 2; grid-row: 1; }
.region-mood { grid-column: 1 / span 2; grid-row: 2; }

.region { background: #23232a; border: 1px solid #34343c; border-radius: 12px; padding: 1.2vw 1.5vw; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.region-title { margin: 0 0 0.8vh 0; font-size: clamp(11px, 1vw, 15px); text-transform: uppercase; letter-spacing: .04em; color: #9a9aa2; font-weight: 600; flex-shrink: 0; }
.region-body { flex: 1; min-height: 0; overflow: hidden; }
.region .empty-state { color: #9a9aa2; font-size: clamp(12px, 1vw, 16px); }

/* A question can be up to 500 characters. Capping the list length isn't
   enough on its own — a single long one could still blow out a card's
   height, so individual items are also clamped to a fixed number of lines
   with an ellipsis. Full text stays intact everywhere else (admin,
   contributor, the CSV export); only this glanceable display truncates. */
.q-card { display: flex; justify-content: space-between; align-items: center; gap: 1vw; padding: 0.7vh 0; border-bottom: 1px solid #34343c; }
.q-card:last-child { border-bottom: none; }
.q-text { font-size: clamp(12px, 1.05vw, 17px); overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }

.poll-question { font-weight: 600; margin-bottom: 0.8vh; font-size: clamp(12px, 1.1vw, 17px); }

/* Carousel mode: one region fills the whole main area at a time, so
   everything inside it can run noticeably larger than the dashboard's
   compact equivalent — same markup and classes, different scale purely
   from this ancestor context. */
.main-area.carousel-frame { display: flex; flex-direction: column; height: 100%; }
.main-area.carousel-frame .region--full { flex: 1; padding: 2vw 3vw; }
.main-area.carousel-frame .region-title { font-size: clamp(1.1rem, 2.2vw, 2.2rem); margin-bottom: 2vh; }
.main-area.carousel-frame .q-text { font-size: clamp(1rem, 2vw, 1.8rem); -webkit-line-clamp: 3; }
.main-area.carousel-frame .poll-question { font-size: clamp(1.2rem, 2.4vw, 2.2rem); margin-bottom: 2vh; }
.main-area.carousel-frame .poll-option-label { font-size: clamp(0.9rem, 1.8vw, 1.5rem); }
.main-area.carousel-frame .poll-bar-track { height: 1.4vw; }
.main-area.carousel-frame .poll-bar-fill { height: 1.4vw; }
.main-area.carousel-frame .theme-card { font-size: clamp(0.9rem, 1.6vw, 1.4rem); padding: 1vw 1.5vw; }
.main-area.carousel-frame .empty-state { font-size: clamp(1rem, 1.8vw, 1.6rem); }
.main-area.carousel-frame .mood-headline { font-size: clamp(1.3rem, 2.6vw, 2.4rem); margin-bottom: 1.5vh; }
.main-area.carousel-frame .sentiment-dot { width: 12px; height: 12px; margin-right: 8px; }

.carousel-dots { display: flex; gap: 8px; justify-content: center; padding-top: 1.5vh; flex-shrink: 0; }
.carousel-dots .dot { width: 8px; height: 8px; border-radius: 50%; background: #4a4a55; }
.carousel-dots .dot.active { background: #7f77dd; }

/* Themes & mood: a bold, coloured headline stating the overall lean before
   any detail, four labelled sentiment bars reusing poll's own row markup
   (so a viewer already knows how to read them from the poll section right
   next to this one), and theme cards each given a distinct accent colour
   purely so they read as four different things rather than one repeated
   shape. */
.mood-headline { font-size: clamp(14px, 1.3vw, 20px); font-weight: 700; margin-bottom: 0.6vh; }
.sentiment-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 4px; }
.sentiment-breakdown { margin-bottom: 0.8vh; }
.theme-card { display: inline-block; margin: 6px; padding: 10px 16px; border-radius: 10px; background: #2a2a33; border-left: 4px solid #7f77dd; }
.theme-quote { font-style: italic; color: #9a9aa2; margin-top: 4px; font-size: 0.9em; }

/* Poll bars — a fixed-width track with a proportional fill, used by both
   the contributor and broadcast views. The track's width never depends on
   its label text, which was the original bug: a flex row was letting the
   percentage text's width push the "bar" around instead. */
.poll-option { display: block; width: 100%; text-align: left; padding: 10px 12px; margin-bottom: 8px; background: #fff; border: 1px solid #ccc; border-radius: 8px; cursor: pointer; font: inherit; }
.poll-option:disabled { cursor: default; opacity: .8; }
.poll-option-label { display: flex; justify-content: space-between; margin-bottom: 6px; }
.poll-bar-track { background: #eee; border-radius: 6px; height: 10px; overflow: hidden; width: 100%; }
.poll-bar-fill { background: #1c1c1a; height: 10px; border-radius: 6px; transition: width .3s ease; }
.broadcast-body .poll-bar-track { background: #34343c; height: 14px; }
.broadcast-body .poll-bar-fill { background: #7f77dd; height: 14px; }

/* Wrap Up: a normal scrolling document, not a variant of the fixed 16:9
   kiosk shell — meant to be read closely during a facilitated discussion,
   not glanced at from across a room, so it gets plain px/rem sizing rather
   than the vw/vh scaling built for the fixed-viewport dashboard/carousel. */
.broadcast-body.wrapup-mode { height: auto; overflow: auto; }

.wrapup-header { display: flex; align-items: center; gap: 20px; padding: 32px 40px 16px; }
.wrapup-logo { width: 140px; height: 70px; object-fit: contain; }
.wrapup-header h1 { margin: 0 0 6px 0; font-size: 28px; }

.wrapup-content { max-width: 900px; margin: 0 auto; padding: 0 40px 60px; }
.wrapup-section { margin-top: 40px; }
.wrapup-section-title { font-size: 14px; text-transform: uppercase; letter-spacing: .04em; color: #9a9aa2; font-weight: 600; margin-bottom: 14px; }

.wrapup-stats { display: flex; flex-wrap: wrap; gap: 12px; }
.stat-card { flex: 1; min-width: 110px; background: #23232a; border: 1px solid #34343c; border-radius: 12px; padding: 16px; text-align: center; }
.stat-number { font-size: 32px; font-weight: 700; color: #7f77dd; }
.stat-label { font-size: 13px; color: #9a9aa2; margin-top: 4px; }

.wrapup-poll-card { margin-bottom: 16px; }

/* Comfortable reading sizes for the components borrowed from the live
   views — not the compact dashboard size (tuned for a cramped shared
   grid) and not the huge carousel size (tuned to be glanceable from
   across a room). Neither fits a page meant to be read up close. */
.wrapup-content .q-text { font-size: 16px; -webkit-line-clamp: unset; overflow: visible; }
.wrapup-content .q-card { gap: 16px; padding: 10px 0; }
.wrapup-content .mood-headline { font-size: 24px; margin-bottom: 10px; }
.wrapup-content .sentiment-dot { width: 10px; height: 10px; margin-right: 6px; }
.wrapup-content .poll-option-label,
.wrapup-content .poll-question { font-size: 15px; }
.wrapup-content .poll-bar-track,
.wrapup-content .poll-bar-fill { height: 12px; }
.wrapup-content .theme-card { font-size: 14px; padding: 12px 18px; }
