/* ============================================================================
   EVENT DETAIL — s/events, FE Client file
     Full event detail   node 23260:442253
     Invitation          node 39296:180830
     Live event          node 17615:295021

   All three frames are ONE page. They differ only in the state of the
   `b/co/event/detail/status/user` card and the header status control, so this
   file styles one page and `data-event-state` selects the state.

   ── The frames are pre-tokenisation. Every colour in them is a LOCAL Figma
   style, not a variable, so none of them was copied. Each was resolved through
   DESIGN.md instead:

   | Figma local style              | resolves to | Token used                    |
   |--------------------------------|-------------|-------------------------------|
   | General/White                  | #ffffff     | `surface/raised`              |
   | General/BG Light               | #f6f6f6     | `soft/neutral/default`        |
   | Text & Icons/Headlines         | #262626     | `content/headline`            |
   | Text & Icons/Primary           | #595959     | `content/primary`             |
   | Text & Icons/Marginal          | #8c8c8c     | `content/secondary`           |
   | Action/BigHeart/Primary        | #4211a0     | `content/brand` (never a hex) |
   | Elements/Border Button Default | #d9d9d9     | `border/default`              |
   | Elements/Borders & Dividers    | #e8e8e8     | `border/default`              |
   | Alert/Success/Primary          | #509e2a     | `content/success`             |
   | Alert/Error/Primary            | #ea0b16     | `solid/danger/default`        |
   | Elements/Other/Likes           | #f5222d     | `content/danger`              |
   | Dial-in link blue              | #0576de     | `content/info`                |

   Two of those are the exact literals root CLAUDE.md forbids a fifth copy of:
   `#4211a0` appears on every link-style button in these frames, and the
   `See all` / `Save` / `Show more` / `See translation` buttons all freeze it.
   They are `Button / Default`, type Link Primary — so they are `.btn--link`
   here and pick the brand up from the token.

   ── Deliberate divergences from the frames, all of them defects named in
   apps/fe-client/CLAUDE.md or COMPONENTS.md:

   D1  `Tag / Entity` — §12 F4: the entity tags use raw pastel/dark pairs, and
       the event-type tag in these frames is a Tags/Pink pair (#fff0f6 on
       #520339). There is no pink ramp in the token system, so reproducing it
       would mean hard-coding two colours with no lineage. The chip is an
       informational category label, so it takes `soft/info` + `on-soft/info`
       and the §4.4 pairing holds. Flagged for the DS.
   D2  The `Accepted` header control reads its state in `content/primary` in
       the frame — status by wording alone, the same shape as §8 F2. The icon
       carries `content/success` / `content/danger` / `content/warning` here,
       which is what button.css already does for the Going / Not going pair.
   D3  No focus and no pressed state exists on any of these components. Both
       are implemented, per DESIGN.md §7 and the CLAUDE.md known gaps.
   D4  The file-type marks (`e/icon/custom/file/*`) are multi-colour brand
       assets — PDF red, DOC blue, Sheet green, PPT gold. They are the one
       icon family that must NOT go through the currentColor mask in
       icons.css, so they are `<img>` elements. ASSETS.md §6 rule 1 is still
       satisfied: the file is referenced, never inlined.

   ── SHARED VOCABULARY. The card shell, `Row / Section Title`, the
   `Sections Items` group heading, `Row / Default`, `e/button v2 ✅ - Context`,
   `Community / All / Detail / Avatar` and `Post / Body / Show More` are the
   SAME DS components the video detail uses. They live once in detail.css,
   under `.detail-*`, and both pages consume them from there. What stays here
   is only what this page does differently, scoped under `.event`.

   TODO(tokens): every bare px length in this file is a SIZE or a BREAKPOINT.
   DESIGN.md §12.4 records both as not built. No colour, radius, spacing,
   border-width or font-size literal appears anywhere in this file.
   ========================================================================== */

.event {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* ============================================================================
   Content object / Header — node I23304:466667;22042:409441
   `p/card/content`: one raised card, hero at 576 and body taking the rest.
   ========================================================================== */

.event-header {
  display: flex;
  align-items: stretch;
  overflow: clip;
  background: var(--color-surface-raised);
  border-radius: var(--shape-radius-card);
}

.event-header__media {
  flex: none;
  /* The frame fixes the hero at 576 of the 1016 measure — 56.7%. Kept as a
     ratio so the card survives the narrower bands instead of overflowing. */
  inline-size: 56.7%;
  /* TODO(tokens): size not built. 324 is the documented card height. */
  min-block-size: 324px;
  background: var(--color-soft-neutral-default);
}

.event-header__img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

.event-header__body {
  display: flex;
  flex: 1 1 auto;
  min-inline-size: 0;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-md);
}

.event-header__top {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: var(--space-xs);
}

/* D1 — see the file header. */
.tag--event-type {
  background: var(--color-soft-info-default);
  border-color: transparent;
  color: var(--color-on-soft-info);
}

.event-header__actions {
  display: flex;
  flex: none;
  align-items: center;
  gap: var(--space-xs);
}

.event-header__main {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--space-xs);
}

.event-header__title {
  margin: 0;
}

/* `Content Object / Date And Time` and `… / Users` — one metadata line each. */
.event-header__meta {
  display: flex;
  margin: 0;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
  color: var(--color-content-primary);
}

.event-header__meta .icon {
  /* TODO(tokens): size not built. 14px is the DS's metadata icon slot. */
  inline-size: 14px;
  block-size: 14px;
  color: var(--color-content-secondary);
}

/* A hairline rule between the two halves of a metadata line, so date and time
   read as two facts rather than one run-on string. */
.event-header__meta-sep {
  inline-size: var(--border-width-thin);
  block-size: var(--font-body-md-size);
  margin-inline: var(--space-3xs);
  background: var(--color-border-default);
}

/* The three counts each carry their own status ink rather than sharing
   content/primary — see the note in index.html and §8 F2. The word is still
   there, so colour is never the only channel. */
.event-header__count--accepted {
  color: var(--color-content-success);
}
.event-header__count--pending {
  color: var(--color-content-warning);
}
.event-header__count--declined {
  color: var(--color-content-danger);
}

/* ============================================================================
   Status control — the header dropdown.

   The frames model the two ends of this: the Invitation frame shows the
   `Respond to invitation` card with Accept / Decline and NO header control;
   the Full detail frame shows `Accepted ⌄` in the header and no card. So the
   control appears once the user has responded, and event.js swaps them.
   ========================================================================== */

.event-status {
  position: relative;
  flex: none;
}

/* The panel opens under the trigger and is narrower than the navbar's, which
   sets a 320 floor for notification rows. This one holds three short labels. */
.event-status .dropdown {
  min-inline-size: 224px;
}

.event-status__icon--accepted {
  color: var(--color-content-success);
}
.event-status__icon--declined {
  color: var(--color-content-danger);
}
.event-status__icon--maybe {
  color: var(--color-content-warning);
}

/* Selection inside the panel already carries tint + ink + weight from
   dropdown.css §6.2. The leading icon adds the status channel on top. */
.event-status .dropdown__item .icon {
  flex: none;
}

/* ============================================================================
   Two-column content — `Content` frame, 576 + 16 + 424 inside the 1016 body.
   ========================================================================== */

.event__content {
  display: flex;
  align-items: start;
  gap: var(--layout-gap);
}

.event__body {
  display: flex;
  flex: 1 1 auto;
  min-inline-size: 0;
  flex-direction: column;
  gap: var(--space-md);
}

.event__side {
  display: flex;
  /* TODO(tokens): size not built. The Sidebar frame is a fixed 424. */
  inline-size: 424px;
  flex: none;
  flex-direction: column;
  gap: var(--space-md);
}

/* Below the point where 576 + 424 no longer fits the middle column, the two
   stack. The body cap is 1016, so this is the same threshold layout.css uses
   for the collapsed band.
   TODO(tokens): breakpoints not built — DESIGN.md §12.4. */
@media (max-width: 1199px) {
  .event__content {
    flex-direction: column;
    align-items: stretch;
  }
  .event__side {
    inline-size: auto;
  }
  .event-header {
    flex-direction: column;
  }
  .event-header__media {
    inline-size: 100%;
    min-block-size: 240px;
  }
}

/* ============================================================================
   b/co/event/detail/status/user — the response / join card.
   One component, two states. Invitation: a prompt + Accept / Decline.
   Live: Join video (Primary) + a Dial-in dropdown.
   ========================================================================== */

.event-respond {
  align-items: center;
  gap: var(--space-xs);
}

.event-respond__prompt {
  margin: 0;
  color: var(--color-content-primary);
}

.event-respond__actions {
  display: flex;
  inline-size: 100%;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
}

/* Both buttons fill half the card in the frame. */
.event-respond__actions .btn {
  flex: 1 1 0;
  min-inline-size: 0;
}

/* Live: Join video takes the slack, Dial-in hugs. */
.event-join {
  display: flex;
  inline-size: 100%;
  align-items: center;
  gap: var(--space-md);
}
.event-join .btn--primary {
  flex: 1 1 auto;
}
.event-join__dialin {
  position: relative;
  flex: none;
}
.event-join__dialin .dropdown {
  min-inline-size: 288px;
}

/* Dial-in rows — `b/co/event/detail/dropdowns`. */
.event-dialin__row {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: var(--space-xs) var(--space-md);
}
.event-dialin__value {
  margin: 0;
  color: var(--color-content-primary);
}
.event-dialin__value a {
  color: var(--color-content-info);
}

/* ============================================================================
   Add to calendar — Redmine #81690.
   Own card rather than a third `.event-join` slot — see the markup comment in
   index.html for why. Below 768px the trigger drops its label (icon-only,
   `aria-label` carries the name) and the panel becomes a bottom sheet instead
   of an anchored popover, per the ticket's business rules.
   ========================================================================== */

.event-calendar__row {
  position: relative;
  display: flex;
}

.event-calendar__trigger-wrap {
  /* Wraps the trigger so a disabled button (pointer-events: none, per
     button.css) can still show its native title tooltip on hover — the
     tooltip has to live on an ancestor that keeps receiving the mouse. */
  display: inline-flex;
}

.event-calendar__menu-header {
  margin: 0;
  padding: var(--space-xs) var(--space-md) 0;
  color: var(--color-content-secondary);
}

/* TODO(tokens): 767px is a BREAKPOINT — not built, DESIGN.md §12.4. Matches
   the value already used throughout this app's @media rules. */
@media (max-width: 767px) {
  .event-calendar__label {
    display: none;
  }

  /* Bottom sheet, not a popover — scoped to this dropdown only so Dial-in and
     the header Status menu keep their existing anchored-popover behaviour. */
  .dropdown--calendar {
    position: fixed;
    inset: auto 0 0 0;
    max-inline-size: none;
    border-radius: var(--shape-radius-menu) var(--shape-radius-menu) 0 0;
  }
}

/* ============================================================================
   b/co/event/detail/countdown
   ========================================================================== */

.event-countdown {
  align-items: center;
  gap: var(--space-none);
}

.event-countdown__label {
  margin: 0;
  color: var(--color-content-primary);
}

.event-countdown__row {
  display: flex;
  align-items: start;
  justify-content: center;
  gap: var(--space-xs);
}

.event-countdown__unit {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* Heading/MD Medium — 20/28. The frame's 1.4 unitless line height is exactly
   the heading/md ratio in DESIGN.md §5.3, so the token pair is right. */
.event-countdown__value,
.event-countdown__colon {
  font-family: var(--font-family-display);
  font-size: var(--font-heading-md-size);
  line-height: var(--font-heading-md-line-height);
  font-weight: var(--font-weight-medium);
  letter-spacing: var(--font-letter-spacing-default);
  color: var(--color-content-headline);
  /* Digits changing every second must not reflow the row. */
  font-variant-numeric: tabular-nums;
}

.event-countdown__unit-label {
  color: var(--color-content-secondary);
  font-size: var(--font-body-sm-size);
  line-height: var(--font-body-sm-line-height);
}

/* ============================================================================
   Community / All / Detail / Description — the page-local half.

   The card shell, the collapse and the `Post / Body / Show More` fade are
   shared — see detail.css. What is specific to this page is the prose itself,
   which is rich text (heading, list, image) rather than the single paragraph
   the video detail renders, and the height it collapses to.
   ========================================================================== */

.event .detail-desc {
  /* TODO(tokens): size not built. 128 shows the lead paragraph and no more,
     which is what the frame's 200-tall collapsed card shows. */
  --detail-desc-collapsed-size: 128px;
}

.event .detail-desc__prose {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  color: var(--color-content-primary);
}

.event .detail-desc__prose > * {
  margin: 0;
}

.event .detail-desc__prose h3 {
  font-family: var(--font-family-display);
  font-size: var(--font-heading-lg-size);
  line-height: var(--font-heading-lg-line-height);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--font-letter-spacing-heading);
  color: var(--color-content-headline);
}

.event .detail-desc__prose ul {
  padding-inline-start: var(--space-lg);
}

.event .detail-desc__prose img {
  inline-size: 100%;
  border-radius: var(--shape-radius-card);
}

/* ============================================================================
   Community / All / Detail / Members — the Accepted card
   ========================================================================== */

.event-people {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.event-people__row {
  display: flex;
  align-items: start;
  gap: var(--space-xs);
}

/* `Community / All / Detail / Avatar` is shared — see detail.css. The one
   page-local difference: the Accepted list sets its names in Medium, which the
   video detail's purchase and sponsor tiles do not. */
.event .detail-person__name {
  font-weight: var(--font-weight-medium);
}

.event-invite {
  inline-size: 100%;
  /* `Invite more people` is a soft-brand full-width action in the frame, not a
     link — the only place `soft/brand` appears on this page. */
  background: var(--color-soft-brand-default);
  border-color: transparent;
  color: var(--color-on-soft-brand);
}
.event-invite:hover {
  background: var(--color-soft-brand-hover);
  border-color: transparent;
}
.event-invite:active {
  background: var(--color-soft-brand-pressed);
}

/* ============================================================================
   b/co/event/detail/attachments — Post / Body / Content / Attachment / Item
   ========================================================================== */

.event-files {
  display: grid;
  /* Two per row in the frame, and the second column's filename is the one that
     has to ellipsis. `minmax(0, 1fr)` is what allows that. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-xs);
}

.event-file {
  display: flex;
  align-items: start;
  gap: var(--space-xs);
  min-inline-size: 0;
}

/* D4 — the file marks keep their own colours, so no mask. */
.event-file__mark {
  flex: none;
  /* TODO(tokens): size not built. 40 is the documented item slot. */
  inline-size: 40px;
  block-size: 40px;
}

.event-file__body {
  display: flex;
  flex: 1 1 auto;
  min-inline-size: 0;
  flex-direction: column;
  justify-content: center;
}

.event-file__name {
  margin: 0;
  color: var(--color-content-primary);
  font-size: var(--font-body-sm-size);
  /* The frame puts Text S on a 22 leading rather than 20 — an off-track value.
     DESIGN.md §5.3 gives body/sm a single line height; used. */
  line-height: var(--font-body-sm-line-height);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.event-file__meta {
  display: flex;
  align-items: baseline;
  gap: var(--space-xs);
}

.event-file__size {
  color: var(--color-content-secondary);
}

/* ============================================================================
   Community / All / Detail / Channels
   ========================================================================== */

.event-channels__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.event-tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}
