
/* ------------------------------------------------------------------ */
/* Messaging enhancements: reaction bar, context menu, reaction chips,
   active bubble highlighting and blur. These classes style the popovers
   and chips for messages across the Plan and Groups tabs to emulate
   the iMessage long‑press UI. */

/* Base reaction bar styling */
/*
 * Reaction bar positioning
 *
 * The reaction bar sits above the active bubble with a small gap and
 * anchors to the left or right edge depending on whether the message
 * is incoming or outgoing.  Using `bottom: calc(100% + 8px)` allows
 * the bar to maintain an 8px gap between itself and the top of the
 * bubble regardless of its height.  Horizontal alignment is handled
 * via the .incoming and .outgoing classes defined below.
 */
.bubble .reaction-bar {
  position: absolute;
  /* Position the bottom of the bar above the top of the bubble by 8px */
  bottom: calc(100% + 8px);
  /* Centre horizontally on the bubble */
  left: 50%;
  transform: translateX(-50%);
  /* Ensure the reaction bar appears above the full‑screen overlay and bubble */
  z-index: 2600;
  padding: 4px 8px;
  background: rgba(55, 65, 81, 0.95);
  color: #fff;
  border-radius: 18px;
  display: flex;
  gap: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.bubble .reaction-bar button {
  all: unset;
  cursor: pointer;
  font-size: 20px;
  line-height: 1;
  margin: 0 2px;
  color: #fff;
}

/* Reaction bar pointer for incoming and outgoing messages.  The pseudo
   element creates a small triangle pointing down at the bubble. */
.bubble .reaction-bar::after {
  content: "";
  position: absolute;
  bottom: -6px;
  width: 0;
  height: 0;
  border-style: solid;
}

/* Horizontal and pointer alignment for reaction bar based on message direction */
/* Incoming reaction bars no longer override horizontal alignment.  The
   bar is centred via the base class; keep only orientation for pointer
   styling. */
.bubble .reaction-bar.incoming {
  right: auto;
}

/* Pointer for incoming messages: small triangle pointing downwards.  The
   pointer is offset from the left edge to align roughly under the first
   emoji. */
/* Centre the pointer under the reaction bar for incoming messages. */
.bubble .reaction-bar.incoming::after {
  left: 50%;
  transform: translateX(-50%);
  border-width: 6px 6px 0;
  border-color: rgba(55, 65, 81, 0.95) transparent transparent;
}

/*
 * Context menu positioning for group chat bubbles
 *
 * When a context menu is attached directly to a message bubble (in
 * group chats), it should appear below the bubble with a small gap
 * and remain anchored to the left or right edge of the bubble
 * depending on whether the message is incoming or outgoing.  These
 * rules override the default context menu styling for menus
 * appended to the document body.
 */
.bubble .context-menu {
  position: absolute;
  top: calc(100% + 8px);
  /* Position above overlay and bubble */
  z-index: 2600;
  /* Match the dark styling of the reaction bar */
  background: rgba(55, 65, 81, 0.95);
  color: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  overflow: hidden;
  font-size: 14px;
  min-width: 140px;
  /* Remove any border from global context menu definitions */
  border: none;
}

.bubble .context-menu .context-item {
  padding: 8px 16px;
  cursor: pointer;
  white-space: nowrap;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  color: #fff;
}

.bubble .context-menu .context-item:last-child {
  border-bottom: none;
}

.bubble .context-menu .context-item:hover {
  background: rgba(255, 255, 255, 0.1);
}

/* Horizontal alignment for bubble-attached menus */
.bubble .context-menu.below.incoming {
  left: 0;
  right: auto;
}
.bubble .context-menu.below.outgoing {
  left: auto;
  right: 0;
}

/* Anchor the reaction bar to the right edge for outgoing messages. */
/* Outgoing reaction bars no longer override horizontal alignment.  The
   bar is centred via the base class; keep only orientation for pointer
   styling. */
.bubble .reaction-bar.outgoing {
  /* Outgoing messages: do not override horizontal centering.  The base
     .reaction-bar rules already set left:50% and translateX(-50%),
     centring the bar over the bubble.  Leaving left unset keeps
     the bar centered regardless of message direction. */
}

/* Pointer for outgoing messages: small triangle offset from the right edge. */
/* Centre the pointer under the reaction bar for outgoing messages. */
.bubble .reaction-bar.outgoing::after {
  left: 50%;
  transform: translateX(-50%);
  border-width: 6px 6px 0;
  border-color: rgba(55, 65, 81, 0.95) transparent transparent;
}

/* Hide the pointer when the reaction bar is centred or promoted to a
   fixed overlay.  These classes are added via JavaScript when the
   reaction bar is displayed in a special mode for tall messages. */
.bubble .reaction-bar.centered::after,
.reaction-bar.fixed-popover::after {
  display: none;
}

/* Promote reaction bar outside of a bubble.  When the reaction bar is
   promoted via JS (i.e. appended to <body> and given the class
   fixed-popover), it must have a high z-index to appear above the
   backdrop overlay.  Without this rule the bar inherits no z-index
   and becomes obscured by the blurred overlay. */
.reaction-bar.fixed-popover {
  /* When the reaction bar is promoted to the document body, it retains
     its pill styling from the bubble version.  Positioning is set
     inline via JavaScript.  Assign a high z-index so it sits above
     the blur overlay. */
  position: fixed;
  z-index: 2600;
  padding: 4px 8px;
  background: rgba(55, 65, 81, 0.95);
  color: #fff;
  border-radius: 18px;
  display: flex;
  gap: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  /* Reset default margins so the bar doesn't inherit unexpected spacing */
  margin: 0;
}

/* Ensure buttons in a promoted reaction bar match the base styling. */
.reaction-bar.fixed-popover button {
  all: unset;
  cursor: pointer;
  font-size: 20px;
  line-height: 1;
  margin: 0 2px;
  color: #fff;
}

/* When the context menu is promoted via JS and given the
   fixed-popover class it retains the default context-menu z-index.
   However for clarity we explicitly set it here. */
.context-menu.fixed-popover {
  z-index: 2600;
}

/* Reaction chips display aggregated counts below the bubble */
.bubble .reaction-chips {
  display: flex;
  gap: 4px;
  margin-top: 4px;
  flex-wrap: wrap;
}

.bubble .reaction-chips span {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  font-size: 12px;
  border-radius: 12px;
  background: rgba(55, 65, 81, 0.1);
  color: #374151;
}

.bubble .reaction-chips span.self-reacted {
  background: rgba(21, 144, 130, 0.2);
  color: #065f46;
}

/* Global context menu styling (appended to body) */
.context-menu {
  position: absolute;
  /* Position above overlay and bubble */
  z-index: 2600;
  background: rgba(55, 65, 81, 0.95);
  color: #fff;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  overflow: hidden;
  font-size: 14px;
  user-select: none;
  min-width: 140px;
}

.context-menu .context-item {
  padding: 8px 16px;
  cursor: pointer;
  white-space: nowrap;
}

.context-menu .context-item:not(:last-child) {
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.context-menu .context-item:hover {
  background: rgba(255, 255, 255, 0.1);
}

/* Pointer for context menu depending on orientation (above/below, incoming/outgoing) */
.context-menu::after {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  border-style: solid;
}

.context-menu.below.incoming::after {
  top: -6px;
  left: 16px;
  border-width: 6px 6px 0;
  border-color: rgba(55, 65, 81, 0.95) transparent transparent;
}

.context-menu.below.outgoing::after {
  top: -6px;
  right: 16px;
  border-width: 6px 6px 0;
  border-color: rgba(55, 65, 81, 0.95) transparent transparent;
}

.context-menu.above.incoming::after {
  bottom: -6px;
  left: 16px;
  border-width: 0 6px 6px;
  border-color: transparent transparent rgba(55, 65, 81, 0.95);
}

.context-menu.above.outgoing::after {
  bottom: -6px;
  right: 16px;
  border-width: 0 6px 6px;
  border-color: transparent transparent rgba(55, 65, 81, 0.95);
}

/* When a context menu is shown in centred mode, hide the pointer arrow to
   avoid a misplaced triangle. */
.context-menu.centered::after {
  display: none;
}

/* When a context menu is promoted to a fixed overlay for tall messages,
   hide the pointer arrow.  This class is applied via JavaScript.
 */
.context-menu.fixed-popover::after {
  display: none;
}

/* Blur and highlight for active context */
#group-chat-thread.context-active .bubble:not(.active-message),
#reflections-thread.context-active .bubble:not(.active-message) {
  filter: blur(3px) brightness(0.8);
  opacity: 0.6;
  pointer-events: none;
}

/*
 * Full-screen overlay used when a message is centred for reactions and
 * context menu.  This overlay applies a blur and dim effect to the
 * entire page so that the active bubble and popovers stand out.  It
 * does not block pointer events on the popovers because it has
 * pointer-events set to none.  The z-index is lower than that of
 * active messages, reaction bars and context menus so those elements
 * appear above the overlay.
 */
.context-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1500;
  backdrop-filter: blur(6px) brightness(0.8);
  background: rgba(255, 255, 255, 0.1);
  pointer-events: none;
}

.bubble.active-message {
  z-index: 2000;
  transform: scale(1.05);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  transition: transform 0.15s ease;
}

/* Snackbar used for undo delete notifications */
.snackbar {
  position: fixed;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  background-color: #374151;
  color: #ffffff;
  padding: 8px 16px;
  border-radius: 8px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
  display: none;
  align-items: center;
  gap: 8px;
}

.snackbar.show {
  display: flex;
}

.snackbar button {
  all: unset;
  text-decoration: underline;
  cursor: pointer;
  font-weight: bold;
}
.chat-body {
  overflow: auto;
}
.chat-stack {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 100%;
}

/*
 * Resources tab styles
 *
 * The resources tab displays a video card for the latest service
 * and one or more podcast cards. Each podcast card contains a
 * header, an audio player bar with custom controls and a list of
 * episodes. These styles ensure the components align nicely and
 * remain responsive on mobile screens.
 */

/* Container for each podcast. It reuses the base .card styles for
   elevation and padding. */
.podcast-card {
  background-color: #ffffff;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  padding: 16px;
  margin-bottom: 16px;
}

/* Header area shows the podcast title. Flex layout allows room
   for future actions if needed. */
.podcast-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

/* Player container uses a column layout to group the controls and
   progress bar. */
/* Podcast player container holds all elements for a single podcast.  It uses
   vertical layout by default and a small gap between rows. */
.podcast-player {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 8px;
}

/* Controls row for play/pause, skip and speed. Align items to the
   center and separate them evenly.  We use flexbox so that the play
   button and skip buttons can have different relative widths. */
.podcast-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Play/pause and skip buttons share the base button styles but use
   tighter padding.  Font size here defines the base size for
   skip buttons; the play button will override this. */
.podcast-controls button {
  padding: 4px 8px;
  font-size: 0.75rem;
}

/* Adjust the play button styling.  Instead of being four times the width
   of the skip buttons, we give the play button a smaller flex value so
   that the skip controls have more space.  The font size and weight
   remain large enough to clearly display the play/pause icon.  We also
   impose a minimum height so that the play and skip buttons match in
   vertical dimension. */
.podcast-play {
  /* Reduced width compared to skip container */
  flex: 2;
  font-size: 1.4rem;
  font-weight: 600;
  padding: 6px 12px;
  min-height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Skip buttons container.  We enlarge the skip controls by giving the
   container a larger flex value than the play button.  Each skip
   button shares equal space within this container.  A minimum height
   ensures the skip buttons align vertically with the play button. */
.podcast-skip-buttons {
  display: flex;
  /* Provide more space for the pair of 15s buttons */
  flex: 3;
  gap: 4px;
}
.podcast-skip-buttons button {
  flex: 1;
  padding: 6px 8px;
  font-size: 0.875rem;
  min-height: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* Speed selector matches the look of other inputs. */
.podcast-speed {
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 4px;
  font-size: 0.875rem;
  color: var(--text-dark);
}

/* Progress bar styling. Removes default styling and adds a
   track/background to match the brand palette. */
.podcast-progress {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  background: #e6e6e6;
  border-radius: 3px;
  cursor: pointer;
}
.podcast-progress::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 12px;
  height: 12px;
  background: var(--primary);
  border-radius: 50%;
  cursor: pointer;
  margin-top: -3px;
}
.podcast-progress::-moz-range-thumb {
  width: 12px;
  height: 12px;
  background: var(--primary);
  border-radius: 50%;
  cursor: pointer;
}

/* Ensure podcast section headings use the same style as the
   primary card headings.  This matches the styling of the
   "Latest Service" heading. */
.podcast-card h3 {
  margin-top: 0;
  color: var(--primary);
  font-size: 1rem;
  font-weight: 600;
}
/* Episode list styles. Each episode is clickable. The active
   episode is highlighted using the accent colour. */
.episode-list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height: 160px;
  overflow-y: auto;
  border-top: 1px solid #e0e0e0;
  margin-top: 8px;
}
.episode-item {
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
  cursor: pointer;
}
.episode-item:hover {
  background-color: rgba(21, 144, 130, 0.05);
}
.episode-item.active {
  background-color: rgba(21, 144, 130, 0.1);
  border-left: 4px solid var(--primary);
  padding-left: 4px;
}

/* Podcast title and meta information inside the list */
.episode-title {
  font-weight: bold;
  margin: 0;
}
.episode-meta {
  font-size: 0.75rem;
  color: #666666;
}

/*
 * Video wrapper for the latest service embed.  Centers the
 * iframe within the card and maintains a responsive aspect ratio.
 */
.video-wrapper {
  width: 100%;
  display: flex;
  justify-content: center;
  margin: 12px 0;
}
.video-wrapper iframe {
  width: 100%;
  max-width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border: none;
}

/*
 * Skip button container within the podcast controls.  This block
 * previously defined a narrower skip area.  It has been removed in
 * favour of the updated definitions above, which allocate more space
 * to the skip controls and ensure consistent heights.  See the
 * .podcast-skip-buttons and .podcast-skip-buttons button rules
 * earlier in this file for the current styles.
 */
/*
 * Core styles for the FBC Provo app prototype.
 * The palette follows the provided brand colors. All elements
 * are styled to look modern, clean and friendly.
 */
:root {
  /* Brand palette */
  --primary: #159082;
  --accent: #19beb6;
  --muted: #92bdb9;
  --light-bg: #f5fcfb;
  --text-dark: #545454;
  --text-light: #ffffff;

  /* Accent color for checkboxes and other small highlights. */
  --check-accent: #1cece9;
}

/* Install button shown when app can be installed */
#install-btn {
  position: fixed;
  top: 12px;
  right: 12px;
  background-color: var(--primary);
  color: var(--text-light);
  border: none;
  border-radius: 20px;
  padding: 8px 16px;
  font-size: 0.875rem;
  cursor: pointer;
  box-shadow: 0 2px 4px rgba(0,0,0,0.2);
  z-index: 1000;
}
#install-btn.hidden {
  display: none;
}

/* Admin panel styles */
.pending-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}
.pending-item button {
  margin-left: 6px;
  font-size: 0.875rem;
  padding: 4px 8px;
}

html, body {
  margin: 0;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  background-color: var(--light-bg);
  color: var(--text-dark);
  height: 100%;
  overflow: hidden;
}

/* Header */
#app-header {
  background-color: var(--light-bg);
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 16px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}

#app-header #logo {
  width: 200px;
  max-width: 80%;
  height: auto;
}

/* Main content area */
#main-content {
  position: absolute;
  top: 80px;
  bottom: 60px;
  left: 0;
  right: 0;
  overflow-y: auto;
  padding: 16px;
  box-sizing: border-box;
}

.tab-content {
  display: none;
}
.tab-content.active {
  display: block;
}


h2 {
  /* Provide more breathing room below the header so page titles don't sit up against it */
  margin-top: 24px;
  color: var(--primary);
}

h3 {
  margin-top: 0;
  color: var(--primary);
}

/* Cards */
.card {
  background-color: #ffffff;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  padding: 16px;
  margin-bottom: 16px;
}

.card ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.card li {
  margin-bottom: 12px;
}

/* Buttons */
button {
  background-color: var(--primary);
  color: var(--text-light);
  border: none;
  border-radius: 4px;
  padding: 8px 12px;
  font-size: 1rem;
  cursor: pointer;
}
button:hover {
  background-color: var(--accent);
}
button:active {
  background-color: var(--primary);
}

/* Acknowledge button uses accent color */
.ack-btn {
  margin-top: 4px;
  background-color: var(--accent);
  color: var(--text-light);
}
.ack-btn:hover {
  background-color: var(--primary);
}

.rsvp-btn, .details-btn {
  margin-right: 8px;
}

/* --------------------------------------------------------------------
 * Events tab button styling
 *
 * The RSVP and “Who's Coming?” buttons in the events list need to be
 * styled consistently.  We borrow the gradient and sizing from the
 * existing rsvp button used in group schedules and add a left margin
 * so the buttons are spaced from each other and the event text.  The
 * attendees button inherits the same look and feel to maintain a
 * cohesive UI.
 */
.events-list .rsvp-btn,
.events-list .attendees-btn {
  margin-left: 8px;
  margin-top: 4px;
}

.attendees-btn {
  padding: 4px 8px;
  background: linear-gradient(to right, var(--primary), var(--accent));
  color: var(--text-light);
  border: none;
  border-radius: 4px;
  font-size: 0.75rem;
  cursor: pointer;
  display: inline-block;
}

.attendees-btn:hover {
  filter: brightness(1.1);
}

/* Helper and empty texts */
.helper-text {
  font-size: 0.875rem;
  color: #777777;
  margin-bottom: 8px;
}

.empty-text {
  font-style: italic;
  color: #777777;
}

/* Reflection and chat threads */
.thread {
  max-height: 200px;
  overflow-y: auto;
  margin-bottom: 8px;
}

/*
 * Group chat conversation layout
 *
 * The group chat thread should behave like a modern messaging app.  The
 * list of messages fills the available space above the input bar,
 * scrolling vertically when there are many messages.  Each message
 * aligns itself left or right (incoming vs. outgoing) while the
 * overall list remains a single flex column.  Messages accumulate
 * from the top of the container and naturally scroll upward as more
 * content is added.
 */
/*
 * The group chat thread is now styled via the .chat-stack class.
 * Any legacy styling on #group-chat-thread has been removed here.  See
 * .chat-stack for layout and spacing rules.
 */

/* Align the group chat input row’s children along the bottom edge.
   This ensures the textarea and send button share the same baseline
   when the textarea grows, keeping the send button vertically
   centred relative to the text field. */
#group-chat-input-row {
  align-items: flex-end;
}
/* Reflection/chat bubbles */
.bubble {
  /* Base bubble styling shared by both sent and received messages. */
  position: relative;
  padding: 10px 14px;
  margin-bottom: 4px;
  /* Give bubbles generous rounding so they resemble iMessage.  The
     18px radius produces pill‑shaped corners. */
  border-radius: 18px;
  /* Prevent the bubble from stretching across the entire screen; this
     width coupled with align‑self overrides creates the familiar
     alternating left/right layout. */
  max-width: 70%;
  word-wrap: break-word;
  border: none;
  /* Disable text selection on bubbles to avoid accidental selection
     when performing long‑press actions. */
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

/* Reply bubbles are indented and use a lighter accent background to
   differentiate them from top-level comments. */
.reply-bubble {
  /* Replies are indented slightly from their parent to indicate
     hierarchy.  A lighter background differentiates them from
     top‑level comments. */
  margin-left: 16px;
  background-color: rgba(25, 190, 182, 0.15);
  /* Maintain a left border accent on top level bubbles only; replies
     receive their accent via the connecting line instead. */
  border-left-color: var(--accent);
  position: relative;
}

/* Attach a connecting line and arrow to reply bubbles.  The line
   runs from the reply back toward its parent and the arrow head
   illustrates the direction of the reply.  Using separate
   pseudo‑elements makes positioning easier. */
/* Draw the connector and arrow using absolute pseudo-elements.  The
   vertical line is aligned with the centre of the arrow head so they
   meet seamlessly.  The arrow points left toward the parent
   comment and uses the darker teal colour for emphasis. */
.reply-bubble::before {
  content: '';
  position: absolute;
  /* Draw a vertical line extending upward to connect to the parent
     bubble.  Place it just to the left of the reply bubble. */
  top: -16px;
  left: -11px;
  width: 2px;
  /* Extend the vertical connector slightly to meet the centre of the
     reply bubble.  Increasing the height by 8px ensures the arrow
     aligns cleanly when it is centred vertically on the reply. */
  height: 36px;
  background-color: var(--accent);
}

.reply-bubble::after {
  content: '';
  position: absolute;
  /* Position the arrow at the bottom of the vertical line and point
     it toward the reply bubble.  The top offset places the base of
     the arrow at the end of the connecting line. */
  /* Position the arrow at the bottom of the vertical line.  The base
     of the arrow sits on the connecting line, and the point aims
     towards the middle of the reply bubble. */
  /* Position the arrow vertically so its point sits roughly at the
     centre of the reply bubble.  The left offset aligns the arrow
     with the vertical connector. */
  top: 10px;
  left: -11px;
  /* Create a right‑pointing triangle by colouring the left border.  In
     CSS triangles the coloured border points toward the direction
     of the arrow.  Using the primary colour makes the arrow
     slightly darker than the line. */
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  /* Use a left border to create a right‑pointing arrow.  The coloured
     border sits on the left side of the pseudo element, which makes
     the arrow point right toward the reply bubble. */
  border-left: 6px solid var(--primary);
}
.bubble-author {
  font-weight: bold;
}

/* ------------------------------------------------------------------ */
/* Plan tab additions: weekly progress bar, catch-up banner, ESV app card,
   and celebration overlays. These styles follow the existing card and
   brand palettes to maintain a cohesive aesthetic throughout the app. */

/* Weekly progress bar container. Use flex layout to evenly space the
   seven segments across the card. */
.weekly-progress-card h3 {
  margin-top: 0;
  margin-bottom: 8px;
}

/*
 * Make the weekly progress bar card sticky so that it remains visible
 * at the top of the viewport as the user scrolls through the daily
 * readings.  Setting position: sticky ensures the element will stick
 * to the top when it would otherwise scroll off the page.  A high
 * z-index keeps it above the reading list content.  We choose top: 0
 * so that the bar adheres directly below the page header once the
 * user scrolls past the controls.  A background colour matching
 * other cards prevents underlying content from showing through.
 */
.weekly-progress-card {
  position: sticky;
  top: 0;
  z-index: 10;
  background-color: var(--card-bg, #ffffff);
  /* Optional: add padding and margin adjustments to prevent
     abrupt jumps when the element becomes sticky. */
}

/*
 * Weekly progress bar
 *
 * The outer container (#weekly-progress) provides a neutral track for the
 * reading progress.  The inner bar (#weekly-progress-inner) grows
 * smoothly from left to right as readings are completed.  The
 * inner bar uses a linear gradient from bright turquoise to deep
 * teal (matching the FBC Provo logo) and has rounded corners so
 * that the bar appears pill‑shaped when fully complete.  A
 * transition on the width makes progress changes feel smooth.
 */
.weekly-progress {
  position: relative;
  width: 100%;
  /* Increase the height of the weekly progress bar so that even a
     single reading increment (1/28th of the week) is visible.  A
     taller bar makes the gradient fill easier to notice and gives
     more room for the inner bar to expand. */
  height: 16px;
  background-color: #e0e0e0;
  border-radius: 6px;
  overflow: hidden;
  margin-top: 4px;
}

.weekly-progress-inner {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0%;
  background: linear-gradient(to right, #19beb6, #159082);
  border-radius: 6px;
  transition: width 0.4s ease;
}

/* Catch-up banner styling. The banner is a card that appears at the top
   of the Plan tab when the user hasn’t completed any readings in
   three or more days. Buttons stack vertically on small screens. */
.catch-up-banner p {
  margin: 0 0 8px 0;
}

.catch-up-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.catch-up-actions button {
  width: 100%;
  font-size: 0.875rem;
  padding: 8px;
}

/* ESV app card: center-align content and space out the download
   buttons. Use platform-specific colours for recognisable branding. */
.esv-app-card {
  text-align: center;
}

.esv-app-card .esv-buttons {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 8px;
}

.esv-app-card .esv-buttons a {
  display: block;
  text-decoration: none;
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 0.875rem;
  color: var(--text-light);
}

/* Platform-specific colours for App Store and Google Play buttons */
.esv-buttons .esv-ios {
  /* Use brand colours instead of platform-specific blue */
  background-color: var(--primary);
}

.esv-buttons .esv-android {
  /* Use brand colours instead of platform-specific green */
  background-color: var(--accent);
}

/* Celebration overlay styling. Covers the entire viewport and centers
   the message card. Hidden by default. */
.celebration-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
}

.celebration-overlay.hidden {
  display: none;
}

.celebration-message {
  text-align: center;
  color: var(--text-light);
  background-color: rgba(21, 144, 130, 0.9);
  padding: 24px;
  border-radius: 12px;
  max-width: 80%;
}

.celebration-message h3 {
  margin: 0 0 8px 0;
  font-size: 1.5rem;
  color: var(--text-light);
}

.celebration-message p {
  margin: 0;
  font-size: 1rem;
  color: var(--text-light);
}

/* Global input styling
 *
 * Apply the turquoise accent colour to the borders of all text inputs and
 * textareas by default.  This overrides the default browser blue
 * highlight and provides a consistent brand look throughout the app.
 */
input[type="text"],
input[type="email"],
input[type="password"],
input[type="date"],
textarea {
  /* Use the brand accent colour for input borders by default.  This
     replaces the browser’s default styling and ties form controls
     into the FBC Provo palette. */
  border: 1px solid var(--accent);
  border-radius: 4px;
}

/* Reading list improvements: allow actions next to each passage.
   Each list item is a flex container with the label on the left and
   action buttons on the right. */
/*
 * A reading list item now contains two rows: a top row with the
 * checkbox, passage title and "Read with ESV" button, and a
 * second row for the embedded audio player.  We use block layout
 * instead of a flex row so that these two rows stack neatly.
 */
#reading-list li {
  display: block;
  margin-bottom: 16px;
}

#reading-list label {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 4px;

  /* Make the passage text more prominent by increasing font size
     and weight. */
  font-size: 1rem;
  font-weight: 600;
}

.reading-actions {
  display: flex;
  gap: 4px;
}

.reading-actions button {
  background-color: var(--accent);
  color: var(--text-light);
  border: none;
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 0.75rem;
  cursor: pointer;
}

.reading-actions button:hover {
  background-color: var(--primary);
}

/* Enlarge reading checkboxes so they’re easier to tap on mobile. */
#reading-list input[type="checkbox"] {
  transform: scale(1.3);
  margin-right: 6px;
}

/*
 * Input and textarea focus states
 *
 * Use the bright turquoise from the FBC palette for the focus border
 * and add a subtle glow.  This replaces the default blue outline
 * across all input fields and textareas in the app.  The box-shadow
 * provides a soft highlight without being too intense.  Remove
 * outlines to avoid conflicting browser styles.
 */
input[type="text"]:focus,
input[type="email"]:focus,
input[type="password"]:focus,
input[type="date"]:focus,
textarea:focus {
  /* When an input gains focus, highlight it with the accent colour
     and a subtle glow.  Using the accent hue at a low opacity for
     the box shadow creates a gentle emphasis without overpowering
     the UI. */
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(25, 190, 182, 0.3);
  outline: none;
}

/* Space the audio player below each reading. */
.audio-container {
  margin-top: 8px;
  width: 100%;
}

/*
 * The top row of each reading item contains the checkbox, passage title,
 * and a button to open the passage in the ESV app.  Using flexbox
 * allows the title to grow while keeping the button aligned to the right.
 */
.reading-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

/* Override the base reading label styles for the top row.  The base
   #reading-list label styles already enlarge the font and weight; here
   we ensure the checkbox and text remain aligned and spaced in the top
   row context. */
.reading-top label {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 1rem;
  font-weight: 600;
}

/* Button used to open the passage on ESV.org.  It shares the same
   accent colours as other buttons in the app but is sized up to
   balance visually with the larger reading label. */
.reading-top .read-btn {
  background-color: var(--accent);
  color: var(--text-light);
  border: none;
  border-radius: 4px;
  /* Increase padding to give the button more height and presence */
  padding: 10px 20px;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
}
.reading-top .read-btn:hover {
  background-color: var(--primary);
}

/* Fireworks pieces used during the day/week completion celebration.
   These are small coloured discs animated via JS.  They do not
   intercept pointer events so underlying buttons remain interactive. */
.firework-piece {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}

.reflection-input {
  display: flex;
  gap: 8px;
  /* Add margin below the input area so that
     chat and reflection message threads are separated
     from the text field. */
  margin-bottom: 12px;
}
.reflection-input textarea {
  flex: 1;
  /* Allow generic textareas (e.g. reflections) to be vertically
     resizable by the user.  A larger minimum height (50px) gives
     extra space for longer reflections.  Specific textarea
     components, such as the group chat input, override these
     defaults with their own class. */
  resize: vertical;
  min-height: 50px;
  /* Use the turquoise accent colour for borders by default */
  border: 1px solid var(--check-accent);
  border-radius: 4px;
  padding: 8px;
  font-family: inherit;
  /* Increase font-size and set dark text colour to prevent iOS from
     auto-zooming and improve readability.  A font size of at least
     16px avoids unexpected zoom in Safari on iOS. */
  font-size: 16px;
  color: var(--text-dark);
}

/* Override styles for the group chat textarea specifically.  This
   ensures the input height matches the send button initially and
   prevents manual resizing which could interfere with the auto‑
   expansion behaviour defined in JavaScript. */
.chat-textarea {
  /* Match the height of the send button (40px). */
  min-height: 40px;
  /* Disable manual resizing; auto expansion is handled via JS. */
  resize: none;
  /* Include padding and border in the height calculation so that
     the minimum height corresponds to the full exterior height of
     the input.  Without this, the padding specified on
     .reflection-input textarea adds extra height beyond 40px. */
  box-sizing: border-box;
}
.reflection-input textarea::placeholder,
.reflection-input input[type="text"]::placeholder {
  /* Ensure placeholder text is legible and a consistent shade.  Without
     this rule, some browsers will reuse previously typed text
     styles when the value is cleared, causing the placeholder to
     appear truncated or oddly coloured. */
  color: #888888;
  opacity: 1;
}
.reflection-input input[type="text"] {
  flex: 1;
  /* Use the turquoise accent colour for borders by default */
  border: 1px solid var(--check-accent);
  border-radius: 4px;
  padding: 8px;
  font-family: inherit;
  /* Match textarea styling for better readability and to prevent
     iOS Safari from zooming the viewport when focusing the input. */
  font-size: 16px;
  color: var(--text-dark);
  /* Match the height of the chat input so both fields appear consistent. */
  /* Slightly reduce the height so it aligns better with the Post button */
  height: 40px;
  line-height: 40px;
  /* Ensure padding and border are included within the specified height */
  box-sizing: border-box;
}

/* Style the inline post/send buttons inside reflection and chat inputs. */
.reflection-input button {
  background-color: var(--accent);
  color: var(--text-light);
  border: none;
  border-radius: 4px;
  padding: 0 16px;
  font-size: 1rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Ensure the button height matches the input height */
  height: 40px;
  line-height: 40px;
}
.reflection-input button:hover {
  background-color: var(--primary);
}

/* Context menu for long‑press interactions on messages */
.context-menu {
  position: absolute;
  z-index: 1000;
  background-color: #ffffff;
  /* Use a slightly thicker border with our accent tint */
  border: 1px solid var(--primary);
  /* Use a larger border radius to create pill‑shaped chat bubbles
     similar to those found in iMessage. */
  border-radius: 18px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  min-width: 160px;
  overflow: hidden;
}
.context-menu .context-item {
  padding: 12px 16px;
  font-size: 16px;
  color: var(--text-dark);
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
.context-menu .context-item:hover {
  background-color: rgba(21, 144, 130, 0.15);
  color: var(--primary);
}

/* Date picker container */
.plan-date-picker {
  margin-bottom: 16px;
}

/* Within the plan controls row, remove the bottom margin on the
   date picker so it aligns flush with the other buttons. */
.plan-controls .plan-date-picker {
  margin-bottom: 0;
}

/* Plan controls row
   The plan controls group the "Continue Plan", "Today’s Reading" and
   date picker into a single horizontal row.  Using flexbox allows
   these controls to wrap on smaller screens.  Gap spacing keeps
   adequate separation between buttons and the calendar field. */
.plan-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: flex-end;
  margin-bottom: 16px;
}

/* Buttons within the plan controls reuse the accent palette and
   adopt comfortable padding for touch.  Hover states darken the
   background slightly. */
.plan-controls button {
  background-color: var(--accent);
  color: var(--text-light);
  border: none;
  border-radius: 4px;
  padding: 8px 12px;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
}

.plan-controls button:hover {
  background-color: var(--primary);
}

/* Style the date picker label to match the brand palette.  Using the
   accent colour here draws attention to the control and ties it into
   the rest of the Plan tab. */
.plan-date-picker label {
  color: var(--accent);
  font-weight: 600;
}

/* Toggles in profile */
.toggle {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}
.toggle input {
  margin-right: 8px;
}

/* Save notice */
.save-notice {
  opacity: 0;
  color: #159082;
  font-weight: bold;
  transition: opacity 0.3s;
}

/* Video embed maintains 16:9 aspect ratio */
.video-embed {
  position: relative;
  padding-bottom: 56.25%; /* 16:9 ratio */
  height: 0;
  overflow: hidden;
  margin-top: 8px;
}
.video-embed iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* Signup modal overlay */
#signup-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 16px;
}
#signup-modal .modal-content {
  background: var(--light-bg);
  border-radius: 8px;
  padding: 24px;
  width: 100%;
  max-width: 420px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}
#signup-modal .modal-content h3 {
  margin-top: 0;
}
#signup-modal input[type="text"],
#signup-modal input[type="email"],
#signup-modal input[type="password"] {
  /* Reduce the field width slightly and centre it within the modal */
  width: 90%;
  padding: 8px;
  margin: 6px auto;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-family: inherit;
  display: block;
}
#signup-modal .role-options {
  display: flex;
  gap: 12px;
  margin: 8px 0;
  /* Center the radio buttons horizontally within the modal */
  justify-content: center;
  align-items: center;
}

/* Align radio inputs and labels inside role options */
#signup-modal .role-options label {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Style the admin passcode input similarly to other inputs and center it */
#admin-passcode-field input {
  width: 90%;
  padding: 8px;
  margin: 6px auto;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-family: inherit;
  display: block;
}
#signup-modal button {
  /* Reduce button width slightly and center it within the modal */
  /* Match the width of input fields and center the button */
  width: 90%;
  padding: 10px;
  margin: 12px auto 0;
}

/* Login modal overlay */
#login-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 16px;
}
#login-modal .modal-content {
  background: var(--light-bg);
  border-radius: 8px;
  padding: 24px;
  width: 100%;
  max-width: 420px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}
#login-modal .modal-content h3 {
  margin-top: 0;
}
#login-modal input[type="email"],
#login-modal input[type="password"] {
  /* Reduce the field width slightly and centre it within the modal */
  width: 90%;
  padding: 8px;
  margin: 6px auto;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-family: inherit;
  display: block;
}
#login-modal button {
  /* Reduce button width slightly and centre it within the modal */
  /* Match the width of input fields and center the login button */
  width: 90%;
  padding: 10px;
  margin: 12px auto 0;
}

/* Remember‑me checkbox styling within the login modal.  This aligns
   the checkbox and its label horizontally and adds spacing around it
   to integrate smoothly with the login form. */
.remember-me {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  margin-bottom: 4px;
  font-size: 0.9rem;
  color: var(--text-dark);
}

/* Link-like text for modal switching */
.link-like {
  color: var(--primary);
  text-decoration: underline;
  cursor: pointer;
}

/* Secondary button style (used for logout) */
.secondary-btn {
  width: 100%;
  padding: 10px;
  margin-top: 8px;
  border: 1px solid var(--primary);
  background-color: transparent;
  color: var(--primary);
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
}
.save-notice.show {
  opacity: 1;
}

/* Bottom navigation with icons */
/*
 * Updated bottom navigation styling with safe-area support and responsive
 * tweaks. The nav now floats slightly above the bottom edge on mobile
 * devices to avoid overlap with gesture bars. Touch targets are
 * comfortable and responsive across phone, tablet and desktop.
 */
#bottom-nav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  /* default height including button area; will adjust via media queries */
  height: 72px;
  display: flex;
  border-top: 1px solid #e0e0e0;
  background-color: #ffffff;
  z-index: 10;
  /* safe area inset ensures nav bar sits above iOS/Android gesture bar.
     Reduce the additional padding so the menu sits slightly lower on
     the screen, helping the active highlight reach the bottom. */
  padding-bottom: max(env(safe-area-inset-bottom, 0px), 8px);
  /* Spread the nav buttons evenly across the full width of the screen.
     Removing the max‑width constraint prevents the far-right tab
     from being pushed out of view on narrow phones.  The nav will
     centre itself on tablets and desktops via the media queries
     defined below. */
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  justify-content: space-around;
}

#bottom-nav button {
  flex: 1;
  border: none;
  background-color: transparent;
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: center;
  padding-top: 8px;
  cursor: pointer;
  min-width: 48px;
  min-height: 48px;
  position: relative;
}
#bottom-nav button svg {
  width: 24px;
  height: 24px;
  stroke: none;
  fill: currentColor;
}
#bottom-nav button.active {
  color: var(--primary);
  /* Extend the active tab highlight into the nav's bottom padding.  We
     achieve this by using an inset box-shadow that extends far
     beyond the button itself.  This ensures the mint green tint
     continues all the way to the bottom edge of the nav, even on
     devices with safe-area insets. */
  background-color: rgba(21, 144, 130, 0.1);
  border-top: 3px solid var(--primary);
  /* Extend the highlight fully to the bottom edge of the viewport.
     Using a very large inset box-shadow ensures the coloured
     background reaches across any safe-area padding on phones
     with gesture bars or cutouts.  Increase the shadow height
     dramatically to handle extreme cases. */
  /* Extend the active highlight even further down so that the mint
     green colour fills the very bottom of the nav bar on phones
     with large gesture areas.  Increasing the inset shadow height
     prevents a thin white line from appearing under the button. */
  /* Extend the highlight extremely far down so that the mint tint fills
     the entire bottom navigation area on all devices, including those with
     large safe‑area insets.  Without a sufficiently large inset shadow
     some devices render a thin white line at the very bottom. */
  box-shadow: 0 9999px 0 rgba(21, 144, 130, 0.1) inset;
}
#bottom-nav button:hover {
  color: var(--accent);
}

/* Smaller phones: slightly shorter nav and smaller bottom padding */
@media (max-width: 360px) {
  #bottom-nav {
    height: 68px;
    padding-bottom: max(env(safe-area-inset-bottom, 0px), 10px);
  }
}

/* Landscape phones: reduce height but keep padding off gesture area */
@media (max-height: 480px) and (orientation: landscape) {
  #bottom-nav {
    height: 60px;
    padding-bottom: max(env(safe-area-inset-bottom, 0px), 8px);
  }
  #bottom-nav button {
    padding-top: 6px;
  }
}

/* Tablets: center nav and lighten footprint */
@media (min-width: 768px) {
  #bottom-nav {
    height: 64px;
    padding-bottom: max(env(safe-area-inset-bottom, 0px), 8px);
    max-width: 840px;
    margin: 0 auto;
    border-radius: 14px 14px 0 0;
  }
}

/* Desktops: treat nav like a floating dock */
@media (min-width: 1024px) {
  #bottom-nav {
    height: 60px;
    padding-bottom: 8px;
    max-width: 960px;
    border-radius: 14px;
    bottom: 16px;
    box-shadow: 0 6px 30px rgba(0,0,0,0.08);
  }
}

/* Group chat view */
/* Hide the group chat container until activated via JavaScript.  When
   visible, the .chat-modal class supplies the grid layout. */
#group-chat {
  display: none;
}
#group-chat.visible {
  display: grid;
}
#group-list .group-item {
  /* Style group items as attractive buttons */
  padding: 12px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  margin-bottom: 12px;
  cursor: pointer;
  font-weight: 600;
  background-color: #ffffff;
  display: flex;
  align-items: center;
  /* Provide space for the group name, preview and chevron.  Use
     flex layout to distribute space such that the preview text can
     grow while the name and arrow remain sized to content. */
  justify-content: flex-start;
  transition: background-color 0.2s, box-shadow 0.2s;
}

/* Small arrow on group items to indicate navigation */
.group-arrow {
  margin-left: 8px;
  font-size: 1.2rem;
  color: var(--muted);
}
#group-list .group-item:hover {
  background-color: rgba(21, 144, 130, 0.05);
  box-shadow: 0 2px 6px rgba(0,0,0,0.08);
}

/* Within a group list item, the group name should be bold and not
   shrink when space is limited. */
#group-list .group-item .group-name {
  font-weight: 600;
  flex-shrink: 0;
}

/* The last message preview grows to fill available space and truncates
   overflow text with an ellipsis. */
#group-list .group-item .group-preview {
  flex: 1;
  margin-left: 8px;
  font-size: 0.85rem;
  color: #666666;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Adjust the chevron arrow on group items to align with the text. */
#group-list .group-item .group-arrow {
  margin-left: 8px;
  font-size: 1rem;
  color: var(--muted);
}

.back-btn {
  margin-bottom: 8px;
  background-color: transparent;
  color: #159082;
  padding: 0;
  font-size: 1rem;
}

/* Ensure inputs expand to full width */
.profile-card input[type="text"],
.profile-card input[type="email"] {
  width: 100%;
  box-sizing: border-box;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  margin-top: 4px;
  margin-bottom: 12px;
  font-family: inherit;
}

.profile-card button {
  margin-top: 8px;
}

/* Utility */
.hidden {
  display: none !important;
}

/* Group chat input and send button.  Mirror the styling of the
   reflection input to maintain consistency across posting areas. */
#group-chat-input {
  flex: 1;
  border: 1px solid var(--check-accent);
  border-radius: 4px;
  padding: 8px;
  font-family: inherit;
  font-size: 16px;
  color: var(--text-dark);
  height: 40px;
  line-height: 40px;
  box-sizing: border-box;
}

/* Highlight the inline group chat input when focused. */
#group-chat-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(25, 190, 182, 0.3);
}
#send-group-msg {
  background-color: var(--accent);
  color: var(--text-light);
  border: none;
  border-radius: 4px;
  padding: 0 16px;
  font-size: 1rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  line-height: 40px;
}
#send-group-msg:hover {
  background-color: var(--primary);
}

/* Directory tab */
.directory-card {
  /* inherits card styling */
}

.directory-controls {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  align-items: center;
}

.directory-controls input[type="text"] {
  flex: 1;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-family: inherit;
}

.directory-controls button {
  padding: 6px 12px;
  font-size: 1.5rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

#add-member-form {
  margin-bottom: 12px;
  background: rgba(21, 144, 130, 0.05);
  padding: 12px;
  border-radius: 8px;
}
#add-member-form input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 8px;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-family: inherit;
}

.add-member-actions {
  display: flex;
  gap: 8px;
}

.cancel-btn {
  background-color: #e0e0e0;
  color: var(--text-dark);
}
.cancel-btn:hover {
  background-color: #d0d0d0;
}

#member-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.member-item {
  display: flex;
  align-items: center;
  padding: 8px;
  border: 1px solid #e0e0e0;
  border-radius: 6px;
  margin-bottom: 8px;
  background-color: #ffffff;
}

.member-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background-color: var(--primary);
  color: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  margin-right: 12px;
  flex-shrink: 0;
}

.member-info {
  flex: 1;
}

.member-name {
  display: block;
  font-weight: bold;
  margin-bottom: 2px;
}

.member-email {
  display: block;
  font-size: 0.85rem;
  color: var(--muted);
}

.copy-email-btn {
  background-color: var(--accent);
  color: #ffffff;
  border: none;
  border-radius: 4px;
  padding: 6px 8px;
  font-size: 0.8rem;
  cursor: pointer;
}
.copy-email-btn:hover {
  background-color: var(--primary);
}

/*
 * Global form controls
 * Set accent color on checkboxes to use the brand turquoise instead of the default browser blue.
 */
input[type="checkbox"] {
  accent-color: var(--check-accent);
}

/*
 * Compose modal styles
 *
 * The compose modal appears when the user clicks on a small
 * reflection or chat input.  It overlays the entire viewport,
 * darkening the background and centring a card with a large
 * textarea.  Users can cancel or submit their post from this
 * overlay.  These styles are appended at the end of the file to
 * avoid interfering with other components.
 */
.compose-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.6);
}

.compose-modal.hidden {
  display: none;
}

.compose-modal-content {
  background-color: #ffffff;
  border-radius: 8px;
  padding: 20px;
  width: 90%;
  max-width: 600px;
  max-height: 80%;
  display: flex;
  flex-direction: column;
}

.compose-modal-content h3 {
  margin-top: 0;
  margin-bottom: 12px;
  font-size: 1.25rem;
  color: var(--primary);
}

/* Create Group button styling inside the groups list card */
#create-group-btn,
.create-group-btn {
  display: block;
  width: 100%;
  margin-bottom: 12px;
  padding: 10px;
  border: none;
  border-radius: 4px;
  background-color: var(--primary);
  color: #ffffff;
  font-size: 1rem;
  cursor: pointer;
}
#create-group-btn:hover,
.create-group-btn:hover {
  background-color: var(--primary-dark, #137f68);
}

/* Create Group modal overlay, styled similarly to the compose modal */
.create-group-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.6);
}
.create-group-modal.hidden {
  display: none;
}
.create-group-modal-content {
  background-color: #ffffff;
  border-radius: 8px;
  padding: 20px;
  width: 90%;
  max-width: 500px;
  max-height: 80%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.create-group-modal-content h3 {
  margin-top: 0;
  margin-bottom: 12px;
  font-size: 1.25rem;
  color: var(--primary);
}
.create-group-modal-content label {
  display: flex;
  flex-direction: column;
  margin-bottom: 12px;
  font-size: 0.9rem;
  color: var(--primary);
}
.create-group-modal-content input[type="text"],
.create-group-modal-content textarea {
  width: 100%;
  padding: 8px;
  border: 1px solid var(--accent);
  border-radius: 4px;
  font-size: 1rem;
  resize: vertical;
}
.create-group-modal-content textarea {
  min-height: 80px;
}
.create-group-modal-content .modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* Group tasks list inside group chat */
.group-tasks {
  margin-top: 16px;
}
.group-tasks h3 {
  margin: 12px 0;
  font-size: 1.1rem;
  color: var(--primary);
}
#group-tasks-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.group-task-item {
  display: flex;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid #eee;
}
.group-task-item input[type="checkbox"] {
  margin-right: 8px;
}
.group-task-item .task-name {
  font-weight: 500;
}
.group-task-item .task-meta {
  font-size: 0.8rem;
  color: var(--text-muted, #555);
}
.add-task-btn {
  margin-top: 12px;
  background-color: var(--accent);
  color: var(--text-light);
  border: none;
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 0.9rem;
  cursor: pointer;
}
.add-task-btn:hover {
  background-color: var(--accent-dark, #14695e);
}

/* Task modal overlay similar to other modals */
.task-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.6);
}
.task-modal.hidden {
  display: none;
}
.task-modal-content {
  background-color: #ffffff;
  border-radius: 8px;
  padding: 20px;
  width: 90%;
  max-width: 500px;
  display: flex;
  flex-direction: column;
}

/* -------------------------------------------------------------------------
 * Group schedule styles
 *
 * The group schedule section lists upcoming events for a group.  It mirrors
 * the styling of the tasks list but uses its own classes so that colours
 * and spacing can be adjusted independently.  A button allows admins or
 * communicators to add new events.  Schedule items show the event name
 * alongside its date/time and optional description.
 */
.group-schedule {
  margin-top: 16px;
}
.group-schedule h3 {
  margin: 12px 0;
  font-size: 1.1rem;
  color: var(--primary);
}
#group-schedule-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.group-schedule-item {
  padding: 8px 0;
  border-bottom: 1px solid #eee;
}
.group-schedule-item .schedule-name {
  font-weight: 500;
}
.group-schedule-item .schedule-meta {
  font-size: 0.8rem;
  color: var(--text-muted, #555);
}
.add-schedule-btn {
  margin-top: 12px;
  background-color: var(--accent);
  color: var(--text-light);
  border: none;
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 0.9rem;
  cursor: pointer;
}
.add-schedule-btn:hover {
  background-color: var(--accent-dark, #14695e);
}

/* Schedule modal overlay similar to other modals */
.schedule-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.6);
}
.schedule-modal.hidden {
  display: none;
}
.schedule-modal-content {
  background-color: #ffffff;
  border-radius: 8px;
  padding: 16px;
  width: 90%;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.schedule-modal-content label {
  display: flex;
  flex-direction: column;
  font-size: 0.9rem;
  color: var(--text-dark);
}
.schedule-modal-content input[type="text"],
.schedule-modal-content input[type="datetime-local"] {
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  margin-top: 4px;
}
.schedule-modal-content textarea {
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  margin-top: 4px;
  min-height: 80px;
}
.schedule-modal-content .modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.task-modal-content h3 {
  margin: 0 0 12px;
  font-size: 1.25rem;
  color: var(--primary);
}
.task-modal-content label {
  display: flex;
  flex-direction: column;
  margin-bottom: 12px;
  font-size: 0.9rem;
  color: var(--primary);
}
.task-modal-content input[type="text"],
.task-modal-content input[type="date"] {
  width: 100%;
  padding: 8px;
  border: 1px solid var(--accent);
  border-radius: 4px;
  font-size: 1rem;
}
.task-modal-content .modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

#compose-modal-text {
  flex: 1;
  resize: vertical;
  border: 1px solid var(--accent);
  border-radius: 4px;
  padding: 8px;
  font-size: 1rem;
  min-height: 200px;
  width: 100%;
  box-sizing: border-box;
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 12px;
}

.modal-actions .btn {
  background-color: var(--accent);
  color: var(--text-light);
  border: none;
  border-radius: 4px;
  padding: 8px 16px;
  font-size: 0.875rem;
  cursor: pointer;
}

.modal-actions .btn:hover {
  background-color: var(--primary);
}

/* -------------------------------------------------------------------------
 * Group members styles
 *
 * The members section displays the list of people belonging to the current
 * group and allows admins/communicators to add new members. Its structure
 * mirrors the tasks and schedule sections, with its own styling for spacing
 * and typography.
 */
.group-members {
  margin-top: 16px;
}
.group-members h3 {
  margin: 12px 0;
  font-size: 1.1rem;
  color: var(--primary);
}
#group-members-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.group-member-item {
  padding: 8px 0;
  border-bottom: 1px solid #eee;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.group-member-item .member-name {
  font-weight: 500;
}
.group-member-item .member-role {
  font-size: 0.8rem;
  color: var(--text-muted, #555);
}
.add-member-btn {
  margin-top: 12px;
  background-color: var(--accent);
  color: var(--text-light);
  border: none;
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 0.9rem;
  cursor: pointer;
}
.add-member-btn:hover {
  background-color: var(--accent-dark, #14695e);
}

/* Member modal overlay similar to other modals */
.member-modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.6);
}
.member-modal.hidden {
  display: none;
}
.member-modal-content {
  background-color: #ffffff;
  border-radius: 8px;
  padding: 16px;
  width: 90%;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.member-modal-content label {
  display: flex;
  flex-direction: column;
  font-size: 0.9rem;
  color: var(--text-dark);
}
.member-modal-content input[type="text"],
.member-modal-content select {
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  margin-top: 4px;
}
.member-modal-content .modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

/* Feature toggle styles within group create/edit modals */
.group-feature-toggles {
  margin: 8px 0;
  font-size: 0.9rem;
}
.group-feature-toggles label {
  display: inline-flex;
  align-items: center;
  margin-right: 12px;
}
.group-feature-toggles input[type="checkbox"] {
  margin-right: 4px;
}

/* Group chat header with edit button */
.group-chat-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}
.group-chat-header h3 {
  margin: 0;
  flex: 1;
}
.edit-group-btn {
  background-color: var(--primary-color);
  color: white;
  border: none;
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 0.9rem;
  cursor: pointer;
}
.edit-group-btn:hover {
  background-color: var(--primary-dark);
}

/* Group feature buttons row displayed in the chat view.  Centers the
   available modules (chat, tasks, schedule) and provides equal
   spacing.  Buttons adapt to the number of enabled features. */
.group-feature-buttons {
  display: flex;
  justify-content: space-around;
  gap: 8px;
  margin-bottom: 12px;
}
.group-feature-buttons button {
  flex: 1;
  padding: 8px;
  font-size: 0.9rem;
  color: #ffffff;
  background-color: var(--primary-color);
  border: none;
  border-radius: 4px;
  cursor: pointer;
  text-align: center;
}
.group-feature-buttons button:hover {
  background-color: var(--primary-dark);
}

/* Full‑screen modals for chat, tasks and schedule.  These overlay
   the entire viewport with a semi‑transparent backdrop.  The
   content containers are centred and fill most of the screen. */
.chat-view-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 101;
}
/* Container styles for the chat, tasks and schedule view modals.
   These modals fill most of the viewport.  The height is reduced
   slightly on mobile to leave room for the bottom nav and safe
   area. */
.chat-view-modal-content {
  background-color: #ffffff;
  border-radius: 8px;
  width: 95%;
  max-width: 600px;
  /* Reduce the height slightly so the modal doesn’t extend off the
     bottom of the viewport on phones.  Using 85vh leaves space
     for the bottom navigation and safe area insets. */
  /* Further reduce the height so the unified group modal is fully
     visible on most phones without cutting off the bottom input.
     This height will still allow space for the modal header and
     tab bar while leaving room above the bottom navigation. */
  height: 80vh;
  display: flex;
  flex-direction: column;
  padding: 16px;
  position: relative;
}

/* Modal header for view modals with a title and close button */
.chat-view-modal-content .modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  /* Remove the bottom border and margin so that the active tab
     highlights can span the full height without being separated by
     thin lines.  Increase the top padding to move the group name
     down and create more breathing room. */
  border-bottom: none;
  padding-bottom: 0;
  margin-bottom: 0;
  padding-top: 16px;
}
.close-modal-btn {
  background: none;
  border: none;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  color: var(--text-dark);
}
/* Chat modal thread area scrolls independently of input.  When there is
   extra vertical space, push the chat bubbles to the bottom so the
   most recent messages sit directly above the compose bar. */
/*
 * Chat panel and body layout
 *
 * The chat panel uses a two‑row CSS grid: the first row (1fr) holds the
 * scrollable chat body and the second row contains the input bar.  The
 * panel itself never scrolls; only the chat body scrolls vertically.
 */
#chat-panel {
  display: grid;
  grid-template-rows: 1fr auto;
  overflow: hidden;
}
/* Chat body: scroll container for conversation bubbles.  It fills
 * available space in the panel and provides vertical scrolling only.
 */
.chat-body {
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding: 12px 0; /* vertical padding; horizontal padding inherited */
}
/* Chat stack: holds individual message bubbles.  Ensures the list grows
 * to fill its parent so justify-content:flex-end can anchor messages
 * at the bottom.  A small gap between bubbles improves readability. */
.chat-stack {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  justify-content: flex-end;
  gap: 8px;
  padding-bottom: 12px;
}
/* The existing ID selector still applies to the message thread.  Apply
 * the same properties as .chat-stack to preserve backwards
 * compatibility with JavaScript that targets #chat-modal-thread. */
#chat-modal-thread {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  justify-content: flex-end;
  gap: 8px;
  padding-bottom: 12px;
}
/* Chat modal input bar styling */
.chat-modal-input {
  display: flex;
  gap: 8px;
}
.chat-modal-input input[type="text"] {
  flex: 1;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
}
.chat-modal-input button {
  padding: 8px 16px;
  background-color: var(--primary-color);
  color: #ffffff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
.chat-modal-input button:hover {
  background-color: var(--primary-dark);
}

/* ------------------------------------------------------------------
 * Unified group modal tweaks
 *
 * The chat modal uses a textarea that auto-expands as the user types and
 * a circular send button with a gradient fill.  Tabs in the modal are
 * highlighted with a gradient when active, and the members button is
 * styled like a pill.  Tasks and schedule panels get refreshed styles.
 */

/* Container for the chat compose area inside the group modal.  Align
   the textarea and send button to the bottom so that the button stays
   anchored even when the textarea grows. */
.chat-modal-input {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  /* Push the compose row to the bottom of the modal panel.  When the
     message list grows, it will take up available space above this
     element. */
  margin-top: auto;
  /* Ensure the compose row spans the full width of the panel.  The
     parent modal provides horizontal padding. */
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}
.chat-modal-input textarea {
  flex: 1;
  resize: none;
  overflow-y: auto;
  /* Match the height of the send button so the input and button align
     initially.  As the user types, the textarea can grow up to
     eight lines, but it starts at the same height as the send
     button. */
  min-height: 40px;
  max-height: calc(1.25em * 8 + 16px);
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  /* Include padding and border in the height calculation so that
     min-height corresponds to the full exterior height.  Without
     border-box the padding adds extra height beyond 40px. */
  box-sizing: border-box;
  font-family: inherit;
  /* Match the posted message font size so typed text appears consistent
     with the chat bubbles. */
  font-size: 1rem;
}

/* Highlight the chat modal textarea when focused.  A faint green
   outline appears around the input to indicate it is active. */
.chat-modal-input textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(25, 190, 182, 0.3);
}
/* Send button styled as a circle with gradient fill.  The arrow symbol
   is white to contrast the gradient background. */
.send-btn {
  width: 40px;
  height: 40px;
  background: linear-gradient(to right, var(--primary), var(--accent));
  color: var(--text-light);
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  cursor: pointer;
}
.send-btn:hover {
  filter: brightness(1.1);
}
/* Members button within the group modal header.  Uses a pill shape and
   gradient fill to stand out. */
.members-btn {
  /* Use a solid brand colour for the members button instead of a gradient.
     This aligns with the rest of the interface where only chat bubbles
     use gradients. */
  background-color: var(--primary);
  color: var(--text-light);
  border: none;
  border-radius: 12px;
  padding: 4px 10px;
  font-size: 0.8rem;
  cursor: pointer;
  margin-right: 8px;
}
.members-btn:hover {
  filter: brightness(1.1);
}
/* Chat bubbles: differentiate messages authored by the current user
   versus those from others.  Self messages use a dark gradient; other
   messages use a muted grey with white text. */
.bubble.self, .Message.outgoing {
  /* Use the brand colours in a diagonal gradient for outgoing
     messages.  White text provides sufficient contrast on the
     coloured background. */
  background: linear-gradient(to bottom right, var(--primary), var(--accent));
  color: var(--text-light);
  /* Align sent messages to the right edge of the thread. */
  align-self: flex-end;
  margin-left: auto;
  /* Attach a small “tail” to the bottom‑right corner.  The tail
     consists of a coloured triangle on top of a white cutout. */
}

/* No tail for outgoing messages; simplified styling */
.bubble.other, .Message.incoming {
  /* Incoming messages use a neutral grey gradient.  Black text
     ensures readability against the pale background. */
  background: linear-gradient(to bottom right, #f2f3f5, #e6e9ec);
  color: var(--text-dark);
  /* Align received messages to the left edge of the thread. */
  align-self: flex-start;
  margin-right: auto;
  /* Outgoing and incoming bubbles share the same border radius. */
}

/* Remove incoming message tail; simplified styling */

.bubble.self .bubble-author,
.bubble.other .bubble-author {
  font-weight: bold;
}

/*
 * Chat modal layout for group conversations.  The modal uses a
 * three-row grid: a fixed-height header, a scrollable body that
 * contains the chat stack, and a fixed-height input bar at the
 * bottom.  This structure ensures messages always appear just above
 * the input and the list stays anchored to the bottom unless the
 * user scrolls up.
 */
.chat-modal {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: #ffffff;
  display: grid;
  grid-template-rows: auto 1fr auto;
  z-index: 1000;
}
.chat-header {
  height: 48px;
  display: flex;
  align-items: center;
  padding: 0 12px;
  border-bottom: 1px solid #e0e0e0;
}
.chat-body {
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding: 12px;
}
.chat-stack {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  justify-content: flex-end;
  gap: 8px;
}
.chat-input-bar {
  display: flex;
  gap: 8px;
  align-items: flex-end;
  padding: 10px 12px;
  border-top: 1px solid #e0e0e0;
  background-color: #ffffff;
}
.chat-input-bar textarea {
  flex: 1;
  min-height: 40px;
  max-height: 160px;
  border: 1px solid #e5e7eb;
  border-radius: 20px;
  padding: 8px 12px;
  resize: none;
  overflow-y: auto;
}
.chat-input-bar button {
  height: 40px;
  border-radius: 20px;
  padding: 0 16px;
}
/* Group task items: card-style with subtle background and border. */
.group-task-item {
  display: flex;
  align-items: flex-start;
  /* Use a subtle gradient for task items to tie into the app’s
     colour palette.  A coloured border on the left helps call
     attention to each task without overwhelming the design. */
  background: linear-gradient(to right, #f6fbfa, #eef7f5);
  border-left: 4px solid var(--primary);
  border-radius: 6px;
  padding: 8px 12px;
  margin-bottom: 8px;
}
.group-task-item input[type="checkbox"] {
  margin-right: 8px;
}
.task-name {
  font-weight: 600;
}
.task-meta {
  font-size: 0.75rem;
  color: var(--text-dark);
}
.task-reminder-btn {
  margin-left: auto;
  padding: 4px 8px;
  background: linear-gradient(to right, var(--primary), var(--accent));
  color: var(--text-light);
  border: none;
  border-radius: 4px;
  font-size: 0.75rem;
  cursor: pointer;
}
.task-reminder-btn:hover {
  filter: brightness(1.1);
}
/* Schedule items styled similarly to tasks. */
.group-schedule-item {
  display: flex;
  flex-direction: column;
  /* Use a subtle gradient and coloured border similar to tasks for
     consistency. */
  background: linear-gradient(to right, #f6fbfa, #eef7f5);
  border-left: 4px solid var(--primary);
  border-radius: 6px;
  padding: 8px 12px;
  margin-bottom: 8px;
}
.schedule-name {
  font-weight: 600;
  margin-bottom: 2px;
}
.schedule-meta {
  font-size: 0.75rem;
  color: var(--text-dark);
}
.rsvp-btn,
.add-calendar-btn {
  margin-top: 4px;
  padding: 4px 8px;
  background: linear-gradient(to right, var(--primary), var(--accent));
  color: var(--text-light);
  border: none;
  border-radius: 4px;
  font-size: 0.75rem;
  cursor: pointer;
  display: inline-block;
}
.rsvp-btn:hover,
.add-calendar-btn:hover {
  filter: brightness(1.1);
}
/* Celebration effect for completed tasks: hearts, stars and Thank You! text rise from the checkbox. */
.task-celebration {
  position: absolute;
  pointer-events: none;
  z-index: 9999;
}
.task-celebration .particle {
  position: absolute;
  font-size: 1rem;
  animation: task-rise 1.6s ease-out forwards;
  opacity: 1;
}
@keyframes task-rise {
  0% { transform: translate(0,0) scale(0.4); opacity: 1; }
  100% { transform: translate(0,-120px) scale(1.2); opacity: 0; }
}

/* Tabs row inside the group modal.  Provides equal width buttons with
   an underline indicator for the active tab. */
.group-modal-tabs {
  display: flex;
  justify-content: space-around;
  /* Reduce the gap below the tabs and eliminate extra horizontal rules.
     The tab bar itself will be separated from the content by its
     bottom padding instead of a margin or border. */
  margin-bottom: 4px;
}
/* Panels stack vertically inside the modal content.  Use flex
   column so children can fill available space.  The hidden class
   will override display to hide inactive panels. */
.group-modal-panel {
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow-y: auto;
}
.group-modal-tab {
  flex: 1;
  /* Increase vertical padding so the highlight fills the full height of
     the tab bar. */
  padding: 12px 0;
  background: none;
  border: none;
  cursor: pointer;
  font-size: 0.9rem;
  color: var(--primary-dark);
  position: relative;
}
.group-modal-tab.active {
  font-weight: 600;
  /* Use a solid brand colour for the active tab instead of a gradient.  This
     keeps the chat/tasks/schedule toggles consistent with other
     controls in the app.  The text is white for contrast. */
  background-color: var(--primary);
  color: var(--text-light);
  border-radius: 6px;
}
/* Remove the underline indicator from active tabs.  The gradient
   background now provides sufficient emphasis. */
.group-modal-tab.active::after {
  content: none;
}

/* Members button in group modal header.  The button styling is
   defined earlier with a gradient fill, so we avoid overriding
   those properties here.  Only set layout-specific margins. */
.members-btn {
  margin-left: auto;
  margin-right: 8px;
}
.members-btn:hover {
  filter: brightness(1.1);
}

/* Members view modal styling, similar to tasks/schedule view */
.members-view-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 101;
}
.members-view-modal-content {
  background-color: #ffffff;
  border-radius: 8px;
  width: 95%;
  max-width: 600px;
  height: 90vh;
  display: flex;
  flex-direction: column;
  padding: 16px;
  position: relative;
}
/* Members view modal header inherits existing modal-header styles */
#members-view-list {
  list-style: none;
  padding: 0;
  margin: 0;
  flex: 1;
  overflow-y: auto;
  margin-bottom: 12px;
}
#members-view-list li {
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
}
#members-view-list li:last-child {
  border-bottom: none;
}

/* Tasks modal list styling */
#tasks-modal-list {
  list-style: none;
  padding: 0;
  margin: 0;
  flex: 1;
  overflow-y: auto;
  margin-bottom: 12px;
}
#tasks-modal-list li {
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
}
#tasks-modal-list li:last-child {
  border-bottom: none;
}

/* Schedule modal list styling */
#schedule-modal-list {
  list-style: none;
  padding: 0;
  margin: 0;
  flex: 1;
  overflow-y: auto;
  margin-bottom: 12px;
}
#schedule-modal-list li {
  padding: 8px 0;
  border-bottom: 1px solid #f0f0f0;
}
#schedule-modal-list li:last-child {
  border-bottom: none;
}

/* ------------------------------------------------------------------
 * Panel list flex behaviour
 *
 * The tasks and schedule panels in the unified group modal include
 * an add button at the top followed by a scrollable list.  These
 * selectors ensure that the lists expand to fill the remaining
 * vertical space and scroll independently from the add button.
 */
#tasks-panel-list,
#schedule-panel-list,
#members-panel-list {
  flex: 1;
  overflow-y: auto;
}

/*
 * Reaction picker styles
 * A floating container with emoji options.  Displays on long press or
 * React selection.  z-index is high to appear above other UI.
 */
.reaction-picker {
  display: flex;
  background-color: #ffffff;
  border: 1px solid #ddd;
  border-radius: 12px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
  padding: 4px;
  z-index: 1000;
}
.reaction-picker span {
  font-size: 20px;
  padding: 4px 6px;
  cursor: pointer;
  user-select: none;
}
/* Reaction bar appended below each message bubble */
.reactions {
  display: flex;
  gap: 4px;
  margin-top: 4px;
  font-size: 16px;
}

/* Reaction popover styles */
.ReactionPopover {
  position: absolute;
  inset: auto 12px 64px auto;
  width: min(280px, 80vw);
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0,0,0,.12);
  padding: 10px 10px 8px;
  z-index: 9999;
}
.ReactionPopover__header {
  display:flex; align-items:center; justify-content:space-between;
  padding: 2px 4px 8px 4px;
  border-bottom:1px solid #f0f0f0;
  margin-bottom:6px;
  font-weight: 600;
}
.ReactionPopover__close {
  background: transparent;
  border: 0;
  font-size: 16px;
  cursor: pointer;
}
.ReactionPopover__list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 40vh;
  overflow: auto;
}
.ReactionPopover__list li {
  display:flex;
  align-items:center;
  gap:8px;
  padding: 8px 6px;
  border-radius: 8px;
}
.ReactionPopover__list li:hover {
  background: #f9fafb;
}
.ReactionPopover__avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #e5e7eb;
  overflow:hidden;
  flex: 0 0 auto;
}
.ReactionPopover__name {
  font-size: 14px;
}

/* ------------------------------------------------------------------ */
/* iMessage long‑press UI (scoped) */
/* Variables controlling colours and shadows used by the tapback and action UI */
:root {
  --surface: #fff;
  --border: #e5e7eb;
  --text: #111827;
  --muted: #6b7280;
  --shadow: 0 12px 30px rgba(0,0,0,.12);
  --danger: #dc2626;
}

.TapbackBar {
  position: absolute;
  z-index: 9999;
  display: flex;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 9999px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  transform-origin: center bottom;
  opacity: 0;
  transform: translateY(6px) scale(.96);
  transition: opacity .15s ease, transform .15s ease;
}
.TapbackBar[data-open="true"] {
  opacity: 1;
  transform: translateY(0) scale(1);
}
.TapbackBtn {
  position: relative;
  min-width: 40px;
  height: 40px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: #fff;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: transform .08s ease;
}
.TapbackBtn:active {
  transform: scale(.95);
}
.TapbackBtn[aria-pressed="true"] {
  background: #f8fffb;
  border-color: #19beb633;
}
.TapbackCount {
  position: absolute;
  top: -6px;
  right: -6px;
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 999px;
  background: #111827;
  color: #fff;
}

.ActionSheet {
  position: absolute;
  z-index: 9999;
  min-width: 180px;
  max-width: 260px;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 12px;
  box-shadow: var(--shadow);
  padding: 6px;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .18s ease, transform .18s ease;
}
.ActionSheet[data-open="true"] {
  opacity: 1;
  transform: translateY(0);
}
.ActionItem {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  padding: 8px 10px;
  border-radius: 8px;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  color: var(--text);
  font: inherit;
}
.ActionItem:hover {
  background: #f7f8fa;
}
.ActionDivider {
  border: 0;
  height: 1px;
  background: var(--border);
  margin: 6px 4px;
}
.ActionItem.destructive {
  color: var(--danger);
}

.ReactionPopover {
  position: absolute;
  z-index: 9999;
  width: min(280px, 90vw);
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 12px;
  box-shadow: var(--shadow);
  padding: 10px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .15s ease, transform .15s ease;
}
.ReactionPopover[data-open="true"] {
  opacity: 1;
  transform: translateY(0);
}
.ReactionPopover__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 6px;
  font-weight: 600;
}
.ReactionPopover__close {
  background: transparent;
  border: 0;
  font-size: 16px;
  cursor: pointer;
}
.ReactionPopover__list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 40vh;
  overflow: auto;
}
.ReactionPopover__list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 6px;
  border-radius: 8px;
}
.ReactionPopover__list li:hover {
  background: #f9fafb;
}

/* RSVP buttons & counts */
.rsvp-btn, .attendees-btn {
  border: 1px solid #ddd;
  background: #fff;
  padding: 8px 10px;
  border-radius: 10px;
  margin-left: 6px;
  cursor: pointer;
  font-size: 14px;
}
.rsvp-btn { border-color: #19beb6; color: #19beb6; }
.rsvp-btn[aria-pressed="true"] { box-shadow: 0 0 0 2px rgba(25,190,182,0.25); }
.attendees-btn { border-color: #545454; color: #545454; }

/* Who's Coming modal */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.45);
  display: flex; align-items: center; justify-content: center; z-index: 10000;
}
.modal-card {
  background: #fff; color: #111; width: min(92vw, 520px);
  border-radius: 14px; box-shadow: 0 10px 40px rgba(0,0,0,0.25);
  overflow: hidden; border: 1px solid #eee;
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px; border-bottom: 1px solid #f1f1f1;
}
.modal-body { padding: 12px 16px; max-height: 60vh; overflow: auto; }
.modal-close { border: 0; background: transparent; font-size: 18px; cursor: pointer; }

/* Fireworks canvas is added dynamically with pointer-events none */
canvas.fireworks-canvas { position: fixed; inset: 0; z-index: 9999; pointer-events: none; }
