/* ===== CSS Variables ===== */
:root {
  --primary-font: 'ManifoldDSA', Arial, sans-serif;
  --monospace-font: 'SpaceMono', monospace;
  --primary-color: #f8ebd7;
  --border-color: #ccc;
  --hover-bg: #f0f0f0;
  --focus-outline: #0066cc;

  /* Read by triggerGavelEffect in timer-remote-shared.js -- aliased here so
     that shared file never has to hardcode a page-specific color. */
  --tr-gavel-red: #EC1F27;
  --tr-gavel-bg: var(--primary-color);
  
  /* Font sizes */
  --font-xs: 8px;
  --font-sm: 9px;
  --font-md: 16px;
  --font-lg: 20px;
  --font-lgr: 40px;
  --font-xl: 48px;
  --font-2xl: 60px;
  
  /* Spacing */
  --gap-xs: 2px;
  --gap-sm: 7px;
  --gap-md: 10px;
  
  /* Dimensions */
  --input-width-sm: 50px;
  --input-width-md: 70px;
  --input-width-lg: 150px;
  --img-height: 115px;
  --button-container-height: 16px;
  
  /* Timing */
  --transition-opacity: 0.2s ease;
}

/* ===== Reset & Base Styles ===== */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* ===== Layout ===== */
body {
  font-family: var(--primary-font);
  display: grid;
  grid-template-rows: 83% 17%;
  grid-template-columns: 21% 79%;
  height: 100vh;
  overflow: hidden;
  gap: 0;
  background-color: var(--primary-color);
}

/* Uploaded slides (#timer2, top-right cell) have no Google-Slides-style
   chrome/bottom bar eating into the content anymore, so they read best as
   close to a true 16:9 rectangle as this grid can get. That cell's shape is
   (column-2 fraction) x (row-1 fraction) of the viewport -- on a 16:9
   screen those two fractions need to be equal to produce a 16:9 cell, so
   this just brings row-1's height down to match column-2's width (79%),
   instead of the default layout's 83%. Toggled by slides.js only while a
   PDF/ODP deck is actually showing -- the pasted-Google-Slides-link mode is
   completely unaffected. */
body.slides-pdf-mode {
  grid-template-rows: 79% 21%;
}

/* "Fullscreen slides" (see toggleFullscreenSlides in slides.js) -- not the
   native Fullscreen API (that requires a direct user gesture in this
   document, which a command arriving from the remote never satisfies, so
   it silently did nothing). The display already runs the whole browser in
   its own real fullscreen, so this just needs to maximize #timer2 within
   the page and hide the other quadrants -- works the same whether it was
   toggled locally or from the remote. */
body.slides-fullscreen > main,
body.slides-fullscreen > footer,
body.slides-fullscreen > #agendaTimer {
  display: none;
}

body.slides-fullscreen #timer2 {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  z-index: 9999;
}

/* Small readouts overlaid on top of fullscreened slides -- countdown at
   bottom-left, up-next item/time at bottom-right. Hidden outside fullscreen
   and whenever their mirrored text is empty (e.g. no next agenda item; see
   updateUpNextDisplay in timer.js), rather than showing an empty pill. */
.fs-overlay {
  display: none;
  position: fixed;
  bottom: 8px;
  z-index: 10000;
  font-size: 8px;
  line-height: 1.2;
  color: var(--primary-color, #f8ebd7);
  background: rgba(0, 0, 0, 0.45);
  padding: 2px 4px;
  border-radius: 6px;
  pointer-events: none;
  white-space: nowrap;
}

.fs-overlay-left { left: 8px; }
.fs-overlay-right { right: 8px; }

body.slides-fullscreen .fs-overlay:not(:empty) {
  display: block;
}

.quadrant {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border: 0;
  padding: 0;
  box-sizing: border-box;
  font-size: var(--font-xs);
}

/* ===== Typography ===== */
@font-face {
  font-family: 'ManifoldDSA';
  src: url('/fonts/ManifoldDSA-Regular.woff2') format('woff2'),
       url('/fonts/ManifoldDSA-Regular.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

.timer {
  font-family: var(--monospace-font);
  font-size: var(--font-2xl);
  margin-bottom: var(--gap-sm);
  font-weight: bolder;
}

.timer-label {
  font-size: var(--font-lgr);
}

.date-time {
  font-family: var(--monospace-font);
  font-size: var(--font-lg);
  text-align: left;
  overflow: visible; /* allow spill into adjacent area */
  line-height: 1.05;
  white-space: normal;
}

/* Ensure date/time box is anchored to the left edge of its container
   so any overflow only goes to the right (never to the left). */
#dateTime {
  /* Fill the quadrant's width so centering of the parent flex doesn't
     cause equal left/right overflow; content can still spill to the right. */
  width: 100%;
  /* Override parent .quadrant align-items: center horizontal centering */
  align-self: stretch;    /* for flex parent -- fill the full cell height so justify-content below has room to anchor to the bottom edge, instead of shrinking to content height and leaving blank space below on a taller screen */
  justify-self: start;    /* for grid parent, harmless otherwise */
  /* Anchors the actual date/time/weather content to the bottom edge of
     this box (which now always spans the full quadrant height, see
     align-self above) -- if the content is ever taller than the quadrant,
     it overflows upward (acceptable) rather than getting its bottom cut
     off, and if the quadrant has extra room, the content still hugs the
     bottom instead of floating with blank space beneath it. */
  justify-content: flex-end;
}

/* ===== Components ===== */

/* Timer-specific styles */

/* Row is: [item name column] [remote widget] -- the label column is the
   only one that grows (flex:1), so the widget always sits flush at the
   right edge, vertically centered, and pushes left as its own width
   changes (idle icon vs. paired QR vs. the open panel). min-width:0 lets
   the label column's own width-fitting logic (timer.js) actually shrink
   instead of the flex item refusing to go below its content's intrinsic
   width. */
#agendaTimer .agenda-row {
  display: flex;
  align-items: center;
  width: 100%;
  gap: var(--gap-md);
}

#agendaTimer .agenda-label-col {
  flex: 1 1 auto;
  min-width: 0;
}

#agendaTimer #agenda-remote-widget-slot {
  flex: 0 0 auto;
  /* Normally a no-op (the slot's own height already matches its content's,
     via .agenda-row's default align-items:center) -- but once .agenda-row
     stretches taller (see the remote-controls-hidden rules below), the
     slot stretches with it and needs this to keep its content from just
     sitting at the top of that extra height instead of centered in it.
     Column direction + flex-end lets a second tab (the skin switcher,
     injected by timer-skin.js) stack above the pairing widget while
     staying flush against the same right edge -- with only one child
     (the common case) this is visually identical to the plain row it
     replaced. */
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 4px;
}

/* "Current Agenda Item" (above) and "Up Next" (below) are small, fixed
   in place, and don't participate in the spacing below. The item name and
   the clock split the row into three equal gaps -- before the name,
   between the name and the clock, and after the clock (which is exactly
   the left edge of the widget, since the widget is the next flex sibling
   after this whole column) -- so a short item name doesn't leave one big
   dead gap sitting right up against the clock. */
#agendaTimer .agenda-prefix-line {
  font-size: 12px;
  opacity: 0.8;
}

#agendaTimer .agenda-label-col p {
  font-size: 11px;
  opacity: 0.75;
  margin-top: 2px;
}

/* Local controls elsewhere are hidden via visibility (not display),
   specifically so the rest of the tuned layout never reflows -- but that
   also means they still occupy their layout space, so simply repositioning
   "Up Next" wouldn't have anywhere to move to. Here specifically, the
   agenda quadrant's control row is allowed to actually collapse when
   hidden (this is the one place a reflow is wanted), and .agenda-row
   stretches to fill the height it frees up, so Up Next can genuinely hug
   the bottom of the quadrant and the gap above it (between the title and
   Up Next) is free for the auto-fit title logic (see setupAgendaLabelAutoFit
   in timer.js) to use for a bigger/multi-line title. */
body.remote-controls-hidden #agendaTimer .button-container.remote-hideable {
  display: none;
}

body.remote-controls-hidden #agendaTimer .agenda-row {
  flex: 1 1 auto;
  align-self: stretch;
  align-items: stretch;
}

/* space-between (not a margin-top:auto on just the <p>) so the title row
   -- and the clock inside it -- lands vertically centered in the freed-up
   height too, not pinned to the top with all the slack dumped above Up
   Next: prefix-line at the top, Up Next at the bottom, title row getting
   an even gap on both sides between them. */
body.remote-controls-hidden #agendaTimer .agenda-label-col {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

#agendaTimer .agenda-title-row {
  display: flex;
  align-items: center;
  justify-content: space-evenly;
  gap: var(--gap-md);
}

#agendaTimer .agenda-title-row .timer {
  flex: 0 0 auto;
}

#agendaTimer .timer-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Button container */
.button-container {
  display: flex;
  gap: var(--gap-xs);
}

/* Buttons */
button {
  font-size: var(--font-sm);
  cursor: pointer;
  transition: opacity var(--transition-opacity);
}

button:disabled {
  opacity: 0.2;
  cursor: not-allowed;
}

/* Unified play/pause toggle button state styling */
.play-pause-btn.is-running {
  background: linear-gradient(135deg, #2c7a00, #4caf50);
  color: #fff;
  font-weight: 600;
}

.play-pause-btn.is-running:hover:not(:disabled) {
  filter: brightness(1.08);
}

button:hover:not(:disabled) {
  background-color: var(--hover-bg);
}

button:focus {
  outline: 4px solid var(--focus-outline);
}

/* Input fields */
.time-input {
  font-size: var(--font-md);
  width: var(--input-width-md);
  text-align: center;
}

.label-input {
  font-size: var(--font-xs);
  width: var(--input-width-lg);
  text-align: center;
}

.speaker-time-input,
.agenda-time-input {
  width: var(--input-width-sm);
}

/* ===== Utility Classes ===== */
.mt-10 {
  margin-top: var(--gap-md);
}

.text-center {
  text-align: center;
}

.h-130 {
  height: var(--img-height);
}

/* The three decor images (roses + chapter logo) share one height that's
   computed in index.html (see the inline script right after this div) so
   the group scales down together to fit the quadrant's width -- these
   height/width values are just the pre-JS/fallback state. */
.index-decor {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--gap-md);
  width: 100%;
}

.index-decor img {
  height: var(--img-height);
  width: auto;
}

/* Set by renderChairName in timer-remote-sync.js -- empty text collapses to
   nothing visible, so no extra hide/show logic is needed here. #chair-name-mobile
   is hidden by default and only shown by the mobile media query below;
   #chair-name-desktop is the reverse (visible by default, hidden there). */
.chair-name-display {
  width: 100%;
  text-align: center;
  font-family: var(--primary-font);
  font-size: var(--font-md);
  font-weight: 700;
  margin-top: var(--gap-sm);
}

#chair-name-mobile {
  display: none;
}

.vote-tally-shell {
  width: 100%;
  margin-top: var(--gap-sm);
  padding: 8px 10px;
  border: 1px solid rgba(236, 31, 39, 0.35);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.5);
}

.vote-tally-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.vote-tally-kicker {
  font-size: var(--font-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
  color: #5f5f5f;
}

.vote-tally-status {
  font-size: var(--font-xs);
  font-weight: 700;
  color: #7a7a7a;
}

.vote-tally-status.open { color: #145a32; }
.vote-tally-status.closed { color: #7f1d1d; }

/* Whether the linked proxy-vote-counter check-in page has its own host
   connected -- empty (see renderLinkedCheckinStatus) until a round has ever
   linked a check-in code, so this collapses to nothing before that. */
.vote-linked-checkin-status {
  display: block;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #7a7a7a;
}

.vote-linked-checkin-status.connected { color: #145a32; }
.vote-linked-checkin-status.disconnected { color: #7f1d1d; }

.vote-tally-title {
  margin: 4px 0 8px;
  font-size: var(--font-md);
  line-height: 1.2;
  text-align: left;
}

.vote-tally-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(108px, 1fr));
  gap: 6px;
}

.vote-option-cell {
  border: 1px solid rgba(0, 0, 0, 0.14);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.75);
  padding: 6px;
  text-align: center;
}

/* The one option currently accepting scans (see renderVotingState in
   timer-remote-sync.js) -- at most one cell ever carries this at once. */
.vote-option-cell.is-open {
  border-color: #145a32;
  background: rgba(20, 90, 50, 0.12);
}

.vote-option-cell.is-closed {
  opacity: 0.6;
}

.vote-option-label {
  font-size: var(--font-xs);
  color: #444;
  margin-bottom: 2px;
}

.vote-option-count {
  font-size: var(--font-lg);
  font-weight: 800;
  color: #111;
}

.vote-option-sub {
  font-size: 10px;
  color: #666;
}

.vote-tally-foot {
  margin-top: 6px;
  font-size: 11px;
  color: #666;
  text-align: left;
}

body.tr-votes-live #index-decor-row {
  display: none;
}

.h-16 {
  height: var(--button-container-height);
}

.h-14 {
  height: 14px;
}

/* ===== Special States ===== */
.resume-glow {
  background: linear-gradient(135deg, #eaff00, #fff65a);
  box-shadow: 0 0 0 2px #b1b500 inset, 0 0 10px rgba(234, 255, 0, 0.8);
  color: #000;
  font-weight: 700;
}

.resume-glow:hover {
  filter: brightness(1.05);
}

#slides-fullscreen-btn.active {
  background: linear-gradient(135deg, #2c7a00, #4caf50);
  color: #fff;
  font-weight: 700;
}

/* ===== Radio Highlight & Keyboard Focus ===== */
input[type="radio"][name="speakerTimerType"],
input[type="radio"][name="agendaTimerType"] {
  position: relative;
}

/* Highlight the label directly following a checked radio */
input[type="radio"][name="speakerTimerType"]:checked + label,
input[type="radio"][name="agendaTimerType"]:checked + label {
  background: linear-gradient(135deg, #ec1f27 0%, #ff585f 100%);
  color: #fff;
  border-radius: 6px;
  padding: 3px 6px;
  font-weight: 600;
  box-shadow: 0 0 0 2px #941116 inset;
}

/* Keyboard focus ring for radios (applied to label for visibility) */
input[type="radio"][name="speakerTimerType"]:focus + label,
input[type="radio"][name="agendaTimerType"]:focus + label {
  outline: 3px solid var(--focus-outline);
  outline-offset: 2px;
}

/* Smooth hover on labels */
input[type="radio"][name="speakerTimerType"] + label:hover,
input[type="radio"][name="agendaTimerType"] + label:hover {
  background-color: var(--hover-bg);
  border-radius: 6px;
}

/* ===== Mobile / Follower View =====
   Below this width, the fixed 4-quadrant kiosk grid (tuned for a
   projector, viewed from across a room) switches to a single scrolling
   column sized for a phone or tablet held in the hand -- meant for
   following along (see timer-remote-sync.js's follower mode), not for
   running the meeting from a phone. Everything above this breakpoint
   (desktop/laptop/widescreen) is completely untouched: nothing here
   overrides anything outside the media query. */
@media (max-width: 820px) {
  :root {
    /* Projector-scale type is illegible held a foot from your face --
       these cascade into every existing rule that already reads them
       (.timer, .timer-label, .date-time, buttons, inputs...), so nothing
       else in this file needs to change to benefit. */
    --font-xs: 10px;
    --font-sm: 11px;
    --font-md: 14px;
    --font-lg: 16px;
    --font-lgr: 22px;
    --font-xl: 26px;
    --font-2xl: 34px;
  }

  body {
    display: flex;
    flex-direction: column;
    height: auto;
    min-height: 100vh;
    overflow: visible;
  }

  body > main,
  .quadrant {
    width: 100%;
    padding: 14px 16px;
  }

  /* Decor/weather/time-of-day -- not useful on a phone follower view. */
  #dateTime,
  #speakerTimer img {
    display: none;
  }

  /* Chair name moves from below the (now-hidden) decor row to below Up
     Next instead -- see #chair-name-desktop/#chair-name-mobile in
     index.html and .chair-name-display above. */
  #chair-name-desktop {
    display: none;
  }

  #chair-name-mobile {
    display: block;
  }

  .vote-tally-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Toggled by timer.js whenever the speaker timer is off, expired, or has
     been paused for more than 15 seconds -- nothing worth following along
     with in any of those states, and mobile is tight on space. */
  #speakerTimer.tr-mobile-hide {
    display: none;
  }

  /* The slides area no longer gets its height from a grid row's
     percentage, so it needs its own explicit aspect ratio to avoid
     collapsing to 0 height as a flex item. */
  #timer2 {
    aspect-ratio: 16 / 9;
    height: auto;
    flex: 0 0 auto;
  }

  /* The item name and the clock stack instead of sharing a row -- on a
     skinny screen there isn't room for both a legible clock and a legible
     title side by side. timer.js's auto-fit logic reads this same
     flex-direction (not a duplicated breakpoint) to know to stop
     shrinking the title to one line and let it wrap here instead. */
  #agendaTimer .agenda-title-row {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
  }

  #agendaTimer .timer-label {
    /* pre-line still wraps normally and collapses runs of spaces/tabs like
       "normal" did, but also respects a literal \n in an item's label as an
       actual line break -- useful for e.g. a two-line agenda item name. */
    white-space: pre-line;
    overflow: visible;
    text-overflow: unset;
    text-align: center;
  }

  /* Toggle button for the full-agenda overlay (see timer.js) -- top-right
     corner so it doesn't collide with the mobile follow bar's bottom-right
     placement. */
  #mobile-full-agenda-btn {
    display: flex;
    position: fixed;
    top: 14px;
    right: 14px;
    z-index: 9998;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 999px;
    border: none;
    background: rgba(20, 20, 20, 0.85);
    color: #fff;
    font-size: 18px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
    cursor: pointer;
  }

  /* No local controls at all on mobile -- this is a screen for following
     along, not for running the meeting from. display:none (not
     visibility:hidden, unlike the host's own hide-controls toggle) so the
     layout actually collapses instead of leaving empty space. The
     remote-sync widget (pairing/codes/QR) is replaced entirely by the
     mobile-only share bar below -- built in JS (timer-remote-sync.js),
     shown/hidden purely by this media query, never both at once. */
  .remote-hideable,
  #remote-sync-widget {
    display: none !important;
  }

  /* ---- Mobile follower bar (replaces the widget) ---- */
  /* Built unconditionally in JS regardless of viewport (see
     timer-remote-sync.js) and toggles a plain "tr-active" class based on
     whether there's actually a code to share -- this media query is the
     only place that decides icon-bar-vs-desktop-widget, so the breakpoint
     itself is never duplicated in JS. ".tr-active" bumps specificity above
     the always-present "display:none" default below, so no !important
     tug-of-war with anything JS might set inline. */
  #mobile-follow-bar.tr-active {
    display: flex;
  }
}

/* Hidden by default (desktop, or mobile with no active code) -- only ever
   shown by the media query above once JS marks it active. */
#mobile-follow-bar {
  display: none;
  position: fixed;
  right: 14px;
  bottom: 14px;
  z-index: 9999;
  align-items: center;
  gap: 8px;
  background: rgba(20, 20, 20, 0.85);
  border-radius: 999px;
  padding: 8px 10px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
}

#mobile-follow-bar span {
  color: #fff;
  font-family: system-ui, sans-serif;
  font-size: 12px;
  letter-spacing: 0.06em;
  padding: 0 2px;
}

#mobile-follow-bar button {
  background: none;
  border: none;
  color: #fff;
  font-size: 20px;
  line-height: 1;
  padding: 4px;
  cursor: pointer;
}

/* ---- Mobile-only: "view full agenda" button + overlay ----
   Hidden by default (desktop) -- shown only inside the mobile media query
   above, exactly like #mobile-follow-bar. The overlay itself never
   restyles `display` unconditionally (only inside the [hidden]/:not
   pair below), so the `hidden` attribute's own UA default keeps working
   without needing a !important override. */
#mobile-full-agenda-btn {
  display: none;
}

#mobile-full-agenda-overlay[hidden] {
  display: none;
}

#mobile-full-agenda-overlay:not([hidden]) {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 10050;
  background: rgba(0, 0, 0, 0.75);
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.mobile-full-agenda-panel {
  background: #1c1c1c;
  color: #fff;
  border-radius: 12px;
  padding: 14px 16px;
  max-width: 420px;
  width: 100%;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-family: system-ui, sans-serif;
}

.mobile-full-agenda-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 15px;
  font-weight: 700;
}

.mobile-full-agenda-header button {
  background: none;
  border: none;
  color: #fff;
  font-size: 18px;
  cursor: pointer;
  padding: 2px 6px;
}

.mobile-full-agenda-list {
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.mobile-full-agenda-item {
  display: flex;
  gap: 10px;
  padding: 6px 8px;
  border-radius: 6px;
  font-size: 13px;
}

.mobile-full-agenda-time {
  flex: 0 0 auto;
  opacity: 0.75;
  font-family: var(--monospace-font, monospace);
  white-space: nowrap;
}

.mobile-full-agenda-label {
  flex: 1 1 auto;
}

.mobile-full-agenda-item.is-current {
  background: rgba(236, 31, 39, 0.35);
  font-weight: 700;
}

.mobile-full-agenda-item.is-next {
  background: rgba(255, 255, 255, 0.12);
}

.mobile-full-agenda-empty {
  opacity: 0.75;
  font-size: 13px;
}
