/* ==========================================================================
   Black Cambry 2026 — Events Calendar (Slice D)
   --------------------------------------------------------------------------
   Slate-and-pink Cambry visual baseline for the unified Calendar_View.
   Replaces flights.css. Loaded after components.css and styles.css so
   shared primitives can be overridden where the calendar needs.

   Tokens consumed (defined in styles.css :root):
     --color-bg          slate background
     --color-surface     card chrome (one step lighter than bg)
     --color-accent      soft pink accent
     --color-text-muted  muted blue-grey body copy
     --color-on-accent   dark text for surfaces riding the pink accent

   Validates: Requirements 1.4, 2.1, 2.5, 5.4, 14.1, 14.2, 14.3, 14.4, 14.5
   ========================================================================== */

/* --------------------------------------------------------------------------
   View shell
   -------------------------------------------------------------------------- */
.calendar-view {
  /* Allow sticky day headers inside the schedule container. The shell
     itself is a flex column so the header sits above the scrolling
     schedule. */
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding: 1rem;
  font-family: 'Yantramanav', sans-serif;
  color: var(--color-text);
}

.calendar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.5rem 0 1rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  margin-bottom: 1rem;
}

.calendar-header__title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.01em;
}

.calendar-header__add-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  border: none;
  border-radius: 12px;
  padding: 0.55rem 1rem;
  cursor: pointer;
  transition: filter 0.15s, opacity 0.15s;
}

.calendar-header__add-btn:hover:not(:disabled) {
  filter: brightness(1.08);
}

.calendar-header__add-btn:focus-visible {
  outline: 2px solid var(--color-accent-hover);
  outline-offset: 2px;
}

.calendar-header__add-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* --------------------------------------------------------------------------
   Schedule view + sticky day headers
   --------------------------------------------------------------------------
   Day headers stick to the top of the scrolling viewport on mobile; on
   wider viewports the page itself scrolls so the header sticks to the
   top of the document. The slate-tinted backdrop with a soft 4 px
   shadow signals "stuck" without flicker.
   -------------------------------------------------------------------------- */
.schedule-view {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  width: 100%;
}

.schedule-day-group {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.schedule-day {
  /* Sticky inside the scrolling container. The shell sits inside
     <main class="app-main"> which is the natural scroll root in the
     mobile layout, so top: 0 is right relative to that scroll context.
     On wide viewports the body scrolls instead, but the same value
     keeps the header pinned to the top of the visible region. */
  position: sticky;
  top: 0;
  z-index: 5;
  margin: 0;
  padding: 0.65rem 0.85rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.02em;
  text-transform: none;
  border-radius: 12px;
  /* Slate-tinted backdrop with a soft accent kiss. The shadow only
     materializes once the header is stuck (handled by the inline
     gradient depth — there's no JS scroll listener in v1). */
  background-color: color-mix(in srgb, var(--color-surface) 95%, var(--color-accent) 5%);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.25);
}

/* --------------------------------------------------------------------------
   Event_Card chassis
   --------------------------------------------------------------------------
   12 px radius, 16 px padding, type-glyph slot at 24×24, owner-avatar
   halo for the signed-in user's own card. Each card is a flex column
   so the header / body sit naturally without table layout.
   -------------------------------------------------------------------------- */
.event-card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 16px;
  border-radius: 12px;
  background-color: var(--color-surface);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.event-card:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
}

.event-card--mine {
  /* Pink halo on the signed-in user's own card (owner of this flight /
     creator of this group event). Keeps the card distinct without
     dominating the schedule. */
  box-shadow: 0 0 0 2px var(--color-accent), 0 4px 12px rgba(0, 0, 0, 0.45);
}

.event-card__header {
  display: flex;
  align-items: center;
  gap: 0.65rem;
}

.event-card__glyph {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  color: var(--color-accent);
  font-size: 1.1rem;
  line-height: 1;
}

.event-card__glyph svg {
  width: 24px;
  height: 24px;
  display: block;
}

.event-card__title-wrap {
  flex: 1;
  min-width: 0;
}

.event-card__title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.01em;
  /* Truncate very long titles instead of wrapping past the time. The
     full title is reachable through the detail sheet (Slice E). */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.event-card__subtitle {
  margin: 0.1rem 0 0;
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--color-text-muted);
  /* Same truncation rule for the subtitle (passenger / location). */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.event-card__time {
  flex-shrink: 0;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--color-text);
  letter-spacing: 0.01em;
  text-align: right;
}

.event-card__body {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}

.event-card__owner {
  /* Owner glyph on flight cards — single avatar. Hidden by default on
     the placeholder-only group/game cards because the RSVP_Stack
     already pins the creator to the front of the Going column. */
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* --------------------------------------------------------------------------
   .past modifier
   --------------------------------------------------------------------------
   Reduce visual weight on the time strip and the type glyph for events
   that have already passed. The title and the RSVP_Stack remain at
   full opacity so the user can still read them at a glance.
   -------------------------------------------------------------------------- */
.event-card--past .event-card__time,
.event-card--past .event-card__glyph,
.event-card--past .event-card__subtitle {
  opacity: 0.55;
}

.event-card--past .event-card__title,
.event-card--past .rsvp-stack {
  opacity: 1;
}

/* --------------------------------------------------------------------------
   RSVP_Stack
   --------------------------------------------------------------------------
   Avatar-forward attendee strip rendered on every card. Three columns:
   Going / Can't go / Unrsvp'd. Avatars are 32×32 with 8 px overlap and
   a 2 px slate ring (box-shadow) for separation. Empty columns are
   omitted entirely so the stack collapses gracefully on small events.
   -------------------------------------------------------------------------- */
.rsvp-stack {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  align-items: flex-start;
}

.rsvp-column {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-width: 0;
}

.rsvp-column--no .rsvp-count {
  color: var(--color-error);
}

.rsvp-column--going .rsvp-count {
  color: var(--color-success);
}

.rsvp-column--unrsvpd .rsvp-count {
  color: var(--color-text-muted);
}

.rsvp-count {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: lowercase;
  letter-spacing: 0.02em;
}

.rsvp-avatars {
  display: flex;
  align-items: center;
  /* Negative gap creates the 8 px overlap between adjacent avatars.
     The white ring on each avatar keeps them visually separated even
     when overlapped. */
  gap: 0;
}

.rsvp-avatars > .rsvp-avatar + .rsvp-avatar,
.rsvp-avatars > .rsvp-avatar + .rsvp-overflow-chip,
.rsvp-avatars > .rsvp-overflow-chip + .rsvp-avatar {
  margin-left: -8px;
}

.rsvp-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  /* The "white-ring" separation between overlapping avatars. The ring
     is the slate surface color so the avatars feel embedded in the
     card chrome rather than floating above it. */
  box-shadow: 0 0 0 2px var(--color-surface);
  background-color: var(--color-primary);
  object-fit: cover;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text);
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  flex-shrink: 0;
  /* Padding so the .tap-target floor (32 × 32 visible avatar inside a
     padded hit area) lands at ≥ 1936 CSS pixels² with no clipping of
     the visual disc. */
  padding: 0;
}

.rsvp-avatar--placeholder {
  background-color: var(--color-primary);
  color: var(--color-text-muted);
}

.rsvp-avatar--owner {
  /* Owner avatar gets the pink ring instead of the slate ring so the
     primary-passenger / creator glyph stands out at a glance. */
  box-shadow: 0 0 0 2px var(--color-accent);
}

.rsvp-overflow-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background-color: color-mix(in srgb, var(--color-accent) 28%, var(--color-surface));
  color: var(--color-on-accent);
  font-size: 0.75rem;
  font-weight: 700;
  /* Same slate ring as avatars so the chip blends visually with the
     RSVP_Stack but its pink fill identifies it as an overflow. */
  box-shadow: 0 0 0 2px var(--color-surface);
  flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   Tap_Target floor
   --------------------------------------------------------------------------
   Shared hit-area utility for every interactive control on the
   Calendar_View. Min 32 × 32 visible dimensions with 6 px transparent
   padding so the effective tap target satisfies Req 14's 1936 CSS px²
   floor (32 + 6 + 6 = 44 each side → 1936 px²).
   -------------------------------------------------------------------------- */
.tap-target {
  min-width: 32px;
  min-height: 32px;
  /* Use box-sizing: content-box so 32 × 32 stays the visible disc and
     the padding extends the hit area outward. The avatars are
     explicitly sized to 32 × 32 above, so the padding here adds 6 px
     of transparent hit-area on every side. */
  box-sizing: content-box;
  padding: 6px;
  /* Negative margin to keep the layout grid stable: the visual size
     stays 32 × 32, but the hit area extends into the surrounding gap. */
  margin: -6px;
}

/* When .tap-target is composed onto a button-like element that already
   carries its own padding (e.g. the Add Event header button), drop our
   padding to avoid double-padding. The selector below opts the
   header button out of the avatar-style padding rule. */
.calendar-header__add-btn.tap-target {
  padding: 0.55rem 1rem;
  margin: 0;
}

/* --------------------------------------------------------------------------
   Wide-viewport polish
   --------------------------------------------------------------------------
   At ≥ 900 px the schedule gets a tiny bit more breathing room and the
   day headers gain a slightly more pronounced shadow to mirror the
   elevated card chrome.
   -------------------------------------------------------------------------- */
@media (min-width: 900px) {
  .calendar-view {
    padding: 1.5rem 2rem;
  }
  .schedule-view {
    gap: 1.75rem;
  }
  .schedule-day {
    padding: 0.75rem 1rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
  }
  .event-card {
    padding: 18px 20px;
  }
}

/* --------------------------------------------------------------------------
   Reduced-motion respect
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .event-card,
  .calendar-header__add-btn {
    transition: none;
  }
}


/* ==========================================================================
   Slice E — RSVP toggle, Event_Detail_Sheet, inline error pill
   --------------------------------------------------------------------------
   Toggle controls live in the Event_Card's actions footer. The Event_
   Detail_Sheet uses the native ``<dialog>`` element with both
   ``--mobile`` and ``--modal`` modifiers applied; media queries below
   pick the right rule set per viewport (matches the Add_Expense_Sheet
   pattern from expenses.css). The inline error pill mounts at the top
   of the calendar-view section above the schedule.

   Validates: Requirements 5.1, 5.2, 5.3, 5.4, 5.5, 6.6, 14.1, 14.2,
              14.3, 14.4, 14.5
   ========================================================================== */

/* --------------------------------------------------------------------------
   Event_Card footer + actions slot
   -------------------------------------------------------------------------- */
.event-card__actions {
  /* Sits below the body region. Keeps a small top margin so the toggle
     row reads as a discrete affordance rather than blurring into the
     RSVP_Stack above. */
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  margin-top: 0.25rem;
  padding: 0;
}

/* --------------------------------------------------------------------------
   RSVP toggle — Going / Can't go
   --------------------------------------------------------------------------
   Two pill buttons rendered side-by-side. The currently-selected pill
   gets the ``--active`` modifier (filled accent); the other stays
   transparent with a 1 px slate border. Both satisfy Req 14's hit-area
   floor through the shared ``.tap-target`` class plus their intrinsic
   padding (≥ 36 × 36 on mobile per task 5.4).
   -------------------------------------------------------------------------- */
.rsvp-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.rsvp-toggle__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  min-height: 36px;
  padding: 0.45rem 0.95rem;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--color-text-muted) 35%, transparent);
  background-color: transparent;
  color: var(--color-text);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}

/* Override the default .tap-target padding/margin treatment for these
   pill buttons — the visual padding above already pushes the hit area
   past 1936 CSS px². The ``.tap-target`` class on its own would add
   6 px of transparent padding outside the pill's visible border, which
   makes adjacent toggles overlap on narrow viewports. */
.rsvp-toggle__btn.tap-target {
  padding: 0.45rem 0.95rem;
  margin: 0;
  box-sizing: border-box;
}

.rsvp-toggle__btn:hover:not(:disabled) {
  border-color: var(--color-accent);
  color: var(--color-text);
}

.rsvp-toggle__btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.rsvp-toggle__btn--active {
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
  font-weight: 600;
}

.rsvp-toggle__btn--active:hover:not(:disabled) {
  filter: brightness(1.06);
}

.rsvp-toggle__btn:active:not(:disabled) {
  transform: translateY(1px);
}

/* --------------------------------------------------------------------------
   Inline RSVP error pill
   --------------------------------------------------------------------------
   Mounts at the top of ``.calendar-view`` when ``onRsvpClick`` fails.
   Auto-dismisses after 5 s. Uses the same warning treatment as the
   project's existing toast / pill primitives — slate surface with a
   warm-pink kiss to the left edge so the user notices without losing
   focus on the calendar.
   -------------------------------------------------------------------------- */
.calendar-rsvp-error-pill {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.65rem 0.85rem;
  margin-bottom: 0.75rem;
  border-radius: 12px;
  background-color: color-mix(in srgb, var(--color-error, #e85a8e) 18%, var(--color-surface));
  color: var(--color-text);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 500;
  border-left: 3px solid var(--color-error, #e85a8e);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
  /* Slide-in from the top by 6 px so the appearance is announced
     visually without requiring a heavy animation library. */
  animation: calendar-rsvp-pill-slide-in 0.18s ease-out;
}

@keyframes calendar-rsvp-pill-slide-in {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* --------------------------------------------------------------------------
   Event_Detail_Sheet
   --------------------------------------------------------------------------
   Native ``<dialog>``-based sheet rendered by ``openEventDetailSheet``
   in calendar.js. Both ``--mobile`` and ``--modal`` modifier classes
   are applied at all times; the media queries below decide which set
   wins per viewport (matches the Add_Expense_Sheet pattern from
   expenses.css):

     - ``@media (max-width: 899px)`` — full-screen sheet
     - ``@media (min-width: 900px)`` — centered 600 px modal

   Same 12 px radius, 16 px padding chassis as the Event_Card so the
   sheet reads as an enlarged version of the card the user just tapped.
   -------------------------------------------------------------------------- */
.detail-sheet {
  border: none;
  /* Defer the border-radius / background-color / padding to the
     viewport-specific blocks below — full-screen sheets want zero
     radius on the corners that touch the safe area, while modals at
     ≥ 900 px want the rounded-card chassis. */
  background-color: var(--color-surface);
  color: var(--color-text);
  font-family: 'Yantramanav', sans-serif;
  /* The dialog body is a flex column so header / body stack and the
     body region can scroll independently. */
  display: flex;
  flex-direction: column;
  max-height: 95vh;
  overflow: hidden;
}

.detail-sheet::backdrop {
  background: rgba(0, 0, 0, 0.55);
}

@media (max-width: 899px) {
  .detail-sheet--mobile {
    /* Full-screen sheet at narrow viewports per task 5.4. */
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: 100%;
    max-height: 100%;
    border-radius: 0;
    margin: 0;
    padding: 0;
    /* iOS safe-area insets so the close button + body sit clear of
       the notch and the home-indicator. */
    padding-top: env(safe-area-inset-top, 0);
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
}

@media (min-width: 900px) {
  .detail-sheet--modal {
    /* Centered 600 px modal at wider viewports per task 5.4. */
    width: 600px;
    max-width: 90vw;
    max-height: 90vh;
    margin: 5vh auto;
    border-radius: 12px;
    padding: 0;
  }
}

.detail-sheet__header {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 12px 16px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.detail-sheet__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 8px 12px;
  background: transparent;
  color: var(--color-text-muted);
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.detail-sheet__close.tap-target {
  /* Override the avatar-style tap-target padding pattern — the
     close button already has its own padding above. */
  padding: 8px 12px;
  margin: 0;
  box-sizing: border-box;
}

.detail-sheet__close:hover {
  color: var(--color-text);
  background-color: color-mix(in srgb, var(--color-text-muted) 15%, transparent);
}

.detail-sheet__close:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.detail-sheet__body {
  flex: 1 1 auto;
  overflow-y: auto;
  /* Same 16 px padding chassis as the Event_Card (task 5.4). */
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.detail-sheet__title-block {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.detail-sheet__title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.01em;
}

.detail-sheet__subtitle {
  margin: 0;
  font-size: 0.9rem;
  color: var(--color-text-muted);
}

.detail-sheet__when {
  margin: 0.25rem 0 0;
  font-size: 0.95rem;
  color: var(--color-text);
  font-weight: 500;
}

.detail-sheet__location {
  margin: 0.4rem 0 0;
  font-size: 0.9rem;
  color: var(--color-text);
}

.detail-sheet__notes {
  margin: 0.5rem 0 0;
  font-size: 0.9rem;
  color: var(--color-text);
  /* Notes get the full text in the detail sheet (no truncation per
     task 5.3). Preserve user-entered line breaks. */
  white-space: pre-wrap;
  word-wrap: break-word;
}

.detail-sheet__toggle-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.detail-sheet__columns {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

@media (min-width: 600px) {
  .detail-sheet__columns {
    /* Three columns side-by-side on slightly-wider viewports so the
       Going / Can't go / Unrsvp'd lists read in parallel. */
    flex-direction: row;
    align-items: flex-start;
  }
  .detail-sheet__column {
    flex: 1 1 0;
    min-width: 0;
  }
}

.detail-sheet__column-title {
  margin: 0 0 0.5rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-text);
  text-transform: lowercase;
  letter-spacing: 0.02em;
}

.detail-sheet__column--going .detail-sheet__column-title {
  color: var(--color-success, var(--color-text));
}

.detail-sheet__column--no .detail-sheet__column-title {
  color: var(--color-error, var(--color-text));
}

.detail-sheet__column--unrsvpd .detail-sheet__column-title {
  color: var(--color-text-muted);
}

.detail-sheet__guest-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.detail-sheet__guest {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.25rem 0.35rem;
  border-radius: 8px;
}

.detail-sheet__guest--mine {
  /* Halo on the user's own row so they spot themselves in the list. */
  background-color: color-mix(in srgb, var(--color-accent) 14%, transparent);
}

.detail-sheet__guest--empty {
  color: var(--color-text-muted);
  font-style: italic;
  opacity: 0.7;
}

.detail-sheet__guest-name {
  font-size: 0.9rem;
  color: var(--color-text);
  /* Truncate long display names so the list rows stay aligned. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* --------------------------------------------------------------------------
   Event_Card cursor — opens the detail sheet on click
   --------------------------------------------------------------------------
   Show the pointer cursor so the click affordance is discoverable. The
   RSVP toggle buttons keep their own pointer cursor through the
   default ``button`` styling above.
   -------------------------------------------------------------------------- */
.event-card {
  cursor: pointer;
}

/* --------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .calendar-rsvp-error-pill {
    animation: none;
  }
  .rsvp-toggle__btn {
    transition: none;
  }
}


/* ==========================================================================
   Slice F — Group_Event card extras + Add_Group_Event_Form
   --------------------------------------------------------------------------
   Adds:
     - .event-card__location / .event-card__notes / .event-card__notes-more
       for the fully-realized renderGroupCard treatment (task 6.5).
     - .event-card__manage-actions + .event-card__manage-btn pair for
       creator/admin edit-delete affordances (task 6.6).
     - .event-card__error inline slot for delete failures (task 6.6).
     - .add-event-sheet (with --mobile and --modal modifier classes)
       for the Add_Group_Event_Form (tasks 6.1 / 6.2). Same dialog
       chassis pattern as .detail-sheet, full-screen on mobile and
       centered 600 px modal at ≥ 900 px.

   Validates: Requirements 4.1, 4.2, 4.3, 4.4, 4.6, 4.7, 7.1, 7.7,
              8.1, 8.2, 14.1, 14.3, 15.1, 15.2, 15.3
   ========================================================================== */

/* --------------------------------------------------------------------------
   Group_Event card — location strip, notes, manage actions
   -------------------------------------------------------------------------- */
.event-card__location {
  margin: 0;
  font-size: 0.9rem;
  color: var(--color-text);
  /* Truncate long location strings instead of wrapping past the card
     edge. Full location is reachable through the detail sheet. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.event-card__notes {
  margin: 0;
  font-size: 0.9rem;
  color: var(--color-text);
  /* Honour user-entered line breaks in the notes body. The
     ``escapeHtml`` pass guarantees we still escape every char that
     could break the markup. */
  white-space: pre-wrap;
  word-wrap: break-word;
}

div.event-card__notes {
  /* Slight inline-flex treatment for the truncated wrapper so the
     "more" button sits adjacent to the trailing ellipsis text. */
  display: inline;
}

.event-card__notes-more {
  /* The "more" affordance is a button, not a link, so keyboard /
     screen-reader users can find it. The visual styling matches the
     "show all" pattern from elsewhere in the project (e.g. attendees
     toolbar). */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 0.35rem;
  padding: 4px 10px;
  background: transparent;
  color: var(--color-accent);
  border: 1px solid color-mix(in srgb, var(--color-accent) 40%, transparent);
  border-radius: 999px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.75rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.event-card__notes-more.tap-target {
  /* Override the avatar-style tap-target padding pattern — the button
     already has its own padding above and a more compact visual look
     fits the inline notes context. */
  padding: 4px 10px;
  margin: 0 0 0 0.35rem;
  box-sizing: border-box;
}

.event-card__notes-more:hover {
  background-color: color-mix(in srgb, var(--color-accent) 18%, transparent);
}

.event-card__notes-more:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.event-card__manage-actions {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-right: auto;
}

.event-card__manage-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: 0.4rem 0.85rem;
  background-color: transparent;
  color: var(--color-text);
  border: 1px solid color-mix(in srgb, var(--color-text-muted) 35%, transparent);
  border-radius: 999px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.event-card__manage-btn.tap-target {
  /* Same opt-out pattern as the rsvp-toggle — avoid the avatar-style
     padding extension because the visible padding already exceeds
     1936 CSS px². */
  padding: 0.4rem 0.85rem;
  margin: 0;
  box-sizing: border-box;
}

.event-card__manage-btn:hover {
  border-color: var(--color-accent);
}

.event-card__manage-btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.event-card__manage-btn--delete {
  color: var(--color-error, #e85a8e);
  border-color: color-mix(in srgb, var(--color-error, #e85a8e) 35%, transparent);
}

.event-card__manage-btn--delete:hover {
  border-color: var(--color-error, #e85a8e);
  background-color: color-mix(in srgb, var(--color-error, #e85a8e) 12%, transparent);
}

/* Disabled-state manage buttons (Slice G task 7.2)
   --------------------------------------------------------------------
   Game cards always render the edit/delete affordances so the layout
   stays identical between admin and non-admin viewers. Non-admins see
   the buttons in this greyed visual state with no click handler — the
   ``disabled`` attribute and ``aria-disabled="true"`` together prevent
   pointer + keyboard activation. The buttons keep ``.tap-target`` so
   the hit-area floor (≥ 1936 CSS px²) is preserved per task 7.5. */
.event-card__manage-btn--disabled,
.event-card__manage-btn--disabled:hover,
.event-card__manage-btn--disabled:focus-visible {
  color: var(--color-text-muted);
  border-color: color-mix(in srgb, var(--color-text-muted) 25%, transparent);
  background-color: transparent;
  cursor: not-allowed;
  opacity: 0.55;
  outline: none;
}

.event-card__manage-btn--delete.event-card__manage-btn--disabled,
.event-card__manage-btn--delete.event-card__manage-btn--disabled:hover {
  /* Override the pink delete tint when disabled — match the same
     muted treatment as the disabled edit button so the row reads as
     a single greyed group. */
  color: var(--color-text-muted);
  border-color: color-mix(in srgb, var(--color-text-muted) 25%, transparent);
}

.event-card__error {
  margin: 0;
  padding: 0;
  font-size: 0.8rem;
  color: var(--color-error, #e85a8e);
  min-height: 0;
  /* Hidden until a delete failure populates the slot — the
     ``.event-card__error--visible`` toggle in calendar.js then
     renders it. */
  display: none;
}

.event-card__error--visible {
  display: block;
  margin-top: 0.5rem;
}

/* --------------------------------------------------------------------------
   Add_Group_Event_Form — native <dialog> sheet/modal
   --------------------------------------------------------------------------
   Same dialog chassis pattern as ``.detail-sheet``: both ``--mobile``
   and ``--modal`` modifiers are applied at all times; the media
   queries below pick the right rule set per viewport. Full-screen on
   mobile, centered 600 px modal at ≥ 900 px (task 6.2).
   -------------------------------------------------------------------------- */
.add-event-sheet {
  border: none;
  background-color: var(--color-surface);
  color: var(--color-text);
  font-family: 'Yantramanav', sans-serif;
  display: flex;
  flex-direction: column;
  max-height: 95vh;
  overflow: hidden;
}

.add-event-sheet::backdrop {
  background: rgba(0, 0, 0, 0.55);
}

@media (max-width: 899px) {
  .add-event-sheet--mobile {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: 100%;
    max-height: 100%;
    border-radius: 0;
    margin: 0;
    padding: 0;
    padding-top: env(safe-area-inset-top, 0);
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
}

@media (min-width: 900px) {
  .add-event-sheet--modal {
    width: 600px;
    max-width: 90vw;
    max-height: 90vh;
    margin: 5vh auto;
    border-radius: 12px;
    padding: 0;
  }
}

.add-event-sheet__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 12px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.add-event-sheet__title {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--color-text);
}

.add-event-sheet__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 8px 12px;
  background: transparent;
  color: var(--color-text-muted);
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.add-event-sheet__close.tap-target {
  /* Same close-button override as the detail sheet — its own padding
     already provides the hit area. */
  padding: 8px 12px;
  margin: 0;
  box-sizing: border-box;
}

.add-event-sheet__close:hover {
  color: var(--color-text);
  background-color: color-mix(in srgb, var(--color-text-muted) 15%, transparent);
}

.add-event-sheet__close:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.add-event-sheet__form {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.add-event-sheet__field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.add-event-sheet__field-label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-text);
}

.add-event-sheet__optional {
  font-weight: 400;
  font-size: 0.8rem;
  color: var(--color-text-muted);
  margin-left: 0.25rem;
}

/* Don't redeclare ``.cambry-input`` selectors (per project convention)
   — extend just the tap-target margin override so the form fields
   don't accidentally inherit the negative-margin avatar pattern. */
.add-event-sheet__form .cambry-input.tap-target {
  margin: 0;
  padding: 0.55rem 0.75rem;
  box-sizing: border-box;
}

.add-event-sheet__notes {
  /* Match the textarea sizing to the cambry-input defaults but allow
     vertical resize within the sheet body. */
  min-height: 88px;
  resize: vertical;
  font-family: 'Yantramanav', sans-serif;
}

.add-event-sheet__field-error {
  margin: 0;
  font-size: 0.8rem;
  color: var(--color-error, #e85a8e);
  min-height: 0;
  display: none;
}

.add-event-sheet__field-error--visible {
  display: block;
}

.add-event-sheet__form-error {
  margin: 0;
  font-size: 0.85rem;
  color: var(--color-error, #e85a8e);
  display: none;
}

.add-event-sheet__form-error.add-event-sheet__field-error--visible {
  display: block;
}

.add-event-sheet__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.add-event-sheet__cancel {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: 0.5rem 1rem;
  background-color: transparent;
  color: var(--color-text);
  border: 1px solid color-mix(in srgb, var(--color-text-muted) 35%, transparent);
  border-radius: 999px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.add-event-sheet__cancel.tap-target {
  padding: 0.5rem 1rem;
  margin: 0;
  box-sizing: border-box;
}

.add-event-sheet__cancel:hover {
  border-color: var(--color-accent);
}

.add-event-sheet__cancel:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.add-event-sheet__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: 0.5rem 1.2rem;
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  border: 1px solid var(--color-accent);
  border-radius: 999px;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: filter 0.15s ease, transform 0.1s ease;
}

.add-event-sheet__submit.tap-target {
  padding: 0.5rem 1.2rem;
  margin: 0;
  box-sizing: border-box;
}

.add-event-sheet__submit:hover:not(:disabled) {
  filter: brightness(1.06);
}

.add-event-sheet__submit:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.add-event-sheet__submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.add-event-sheet__submit:active:not(:disabled) {
  transform: translateY(1px);
}

/* --------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .event-card__notes-more,
  .event-card__manage-btn,
  .add-event-sheet__cancel,
  .add-event-sheet__submit {
    transition: none;
  }
}
