/* ==========================================================================
   Black Cambry 2026 — Attendees View (Slice C)
   --------------------------------------------------------------------------
   Per-view stylesheet for the Master Attendees registry view (#attendees).
   Styles a responsive card grid built via the shared ``renderCambryCard``
   factory plus a sticky toolbar that holds the search input and inline
   Add Attendee form.

   Loaded AFTER components.css and AFTER trips.css. The canonical
   .cambry-card surface, slot wrappers, .cambry-input form-field
   treatment, and .cambry-fab floating-pill rules now live in
   components.css (extracted in task 3.7 per Requirement 15.1). What
   remains in this stylesheet is Attendees_View specific: the view shell
   (`.attendees-view`), the sticky toolbar (`.attendees-toolbar*`), the
   inline Add Attendee form (`.attendees-add-form*`), the responsive
   grid (`.attendees-grid*`), the per-card slot content
   (`.attendee-card*`), the inline edit form (`.attendee-edit-form*`),
   the no-match panel (`.attendees-no-match*`), and the Attendees-only
   button chassis (`.attendees-btn*`).

   Tokens consumed (defined in styles.css :root):
     --color-bg          #1f2c38   slate background
     --color-surface     #2a3a4a   card chrome, one step lighter than bg
     --color-primary     #3a526a   chip/button base
     --color-accent      #f896ff   soft pink accent
     --color-on-accent   #1f2c38   dark text for accent fills
     --color-text        #e8edf0   body copy on slate
     --color-text-muted  #a6b7bf   secondary text
     --color-error       #ff8aa1   inline-error tone
     --color-success     #7fd197   inline-success tone
   Typography: Yantramanav (loaded in index.html).
   Requirements covered: 9.1, 9.3, 9.4, 11.1, 12.1, 14.1, 14.3
   ========================================================================== */

/* --------------------------------------------------------------------------
   View shell
   --------------------------------------------------------------------------
   The Attendees view is a stack of three pieces: a title, a sticky
   toolbar (search + add form), and a responsive card grid. The bottom
   padding leaves room so the floating Create Trip pill from Trips_View
   (when both views are admin-rendered in sequence) does not visually
   collide; the pill is teardown'd on hashchange-away by trips.js so this
   is just defense-in-depth.
   -------------------------------------------------------------------------- */
.attendees-view {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.25rem 1rem 6rem;
  max-width: 1400px;
  margin: 0 auto;
  width: 100%;
}

.attendees-view__title {
  font-family: 'Yantramanav', sans-serif;
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--color-text);
  letter-spacing: 0.01em;
  margin: 0;
}

.attendees-view__lead {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 400;
  line-height: 1.4;
  color: var(--color-text-muted);
  margin: 0;
  max-width: 60ch;
}

/* --------------------------------------------------------------------------
   Sticky toolbar — search input + inline Add Attendee form
   --------------------------------------------------------------------------
   The toolbar stays at the top of the viewport while the user scrolls
   the card grid so search and add-attendee remain available without a
   scroll-back-to-top trip. ``top: 0`` parks it under the sticky app
   header (the header has its own stacking context); ``z-index: 4`` is
   below the app header's natural z-index so the toolbar tucks under
   the header rather than overlapping it on long pages.

   Background fill (--color-bg) keeps the cards beneath from bleeding
   through during the sticky transition.
   -------------------------------------------------------------------------- */
.attendees-toolbar {
  position: sticky;
  top: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0.75rem 0;
  background-color: var(--color-bg);
}

.attendees-toolbar__row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0.5rem; /* 8px — adjacent-control spacing per Req 14.3 */
}

.attendees-toolbar__row--search {
  /* Search row stays a single column at every viewport — the input
     spans full width so the touch target is the full 44px-tall row. */
  flex-direction: column;
}

.attendees-toolbar__row--add {
  /* Inline single-row submit layout (Req 12.1). On narrow screens the
     fields wrap onto multiple lines while preserving 8px gaps both
     horizontally and vertically. */
  align-items: flex-end;
}

/* Search input wrapper carries the text input. Kept as a flex column
   so the label can sit above the input without affecting the toolbar
   layout calculation. */
.attendees-search {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  width: 100%;
}

.attendees-search__label {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}

/* Inline Add Attendee form (Req 12.1) — single-row submit layout that
   wraps gracefully on narrow screens. Each field gets its own column
   that flexes to a sensible minimum so the row stays readable on
   320 CSS px viewports. */
.attendees-add-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem;
  width: 100%;
}

.attendees-add-form__field {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  flex: 1 1 12rem;
  min-width: 0;
}

.attendees-add-form__field--checkbox {
  /* Checkbox + label sits inline rather than label-above. */
  flex: 0 0 auto;
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  min-height: 44px; /* tap-target on the wrapper itself */
}

.attendees-add-form__field--actions {
  flex: 0 0 auto;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
}

.attendees-add-form__label {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}

.attendees-add-form__field-error {
  /* Per-field validation message (e.g. "email is required"). Renders
     in the error tone immediately under the offending input. Empty
     state collapses via :empty so non-error rows don't reserve space. */
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--color-error);
  margin: 0;
  min-height: 0;
}

.attendees-add-form__field-error:empty {
  display: none;
}

.attendees-add-form__feedback {
  /* Inline feedback for 4xx/5xx/network-failure on POST (Reqs 12.5,
     12.6). Spans the full row beneath the form fields. */
  flex: 1 1 100%;
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  font-weight: 500;
  margin: 0;
  min-height: 0;
}

.attendees-add-form__feedback:empty {
  display: none;
}

.attendees-add-form__feedback--error {
  color: var(--color-error);
}

.attendees-add-form__feedback--success {
  color: var(--color-success);
}

/* --------------------------------------------------------------------------
   Buttons used by the Attendees view (Save / Cancel / Edit / Delete /
   Add). They consume the same chassis as the trips view's
   .cambry-card__action-btn but live under attendees-specific selectors
   so the Slice C extraction doesn't have to disambiguate.

   Tap-target: 44 × 44 minimum (Req 14.1).
   -------------------------------------------------------------------------- */
.attendees-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0.55rem 1rem;
  border: 1px solid var(--color-primary);
  border-radius: 999px;
  background-color: transparent;
  color: var(--color-text);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.attendees-btn:hover {
  background-color: rgba(248, 150, 255, 0.08);
  border-color: var(--color-accent);
}

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

.attendees-btn:active {
  transform: translateY(1px);
}

.attendees-btn:disabled,
.attendees-btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  border-color: var(--color-primary);
  background-color: transparent;
}

.attendees-btn--primary {
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  border-color: var(--color-accent);
}

.attendees-btn--primary:hover:not(:disabled) {
  background-color: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
}

.attendees-btn--primary:disabled,
.attendees-btn--primary[aria-disabled="true"] {
  background-color: var(--color-primary);
  color: var(--color-text-muted);
  border-color: var(--color-primary);
}

/* Destructive — used by the Delete button. Text-tone red on hover so
   the cascade-warning intent is unmistakable. */
.attendees-btn--danger {
  border-color: var(--color-error);
  color: var(--color-error);
}

.attendees-btn--danger:hover:not(:disabled) {
  background-color: rgba(255, 138, 161, 0.12);
  border-color: var(--color-error);
  color: var(--color-error);
}

/* --------------------------------------------------------------------------
   Responsive card grid (Req 9.4)
   --------------------------------------------------------------------------
   Card column count by viewport width:
     320 –   599 px → 1 column
     600 – 1023 px → 2 columns
   1024+ px → 3+ columns (auto-fill on a 18rem minimum)

   ``minmax(0, 1fr)`` on each column fraction prevents long content from
   stretching the grid wider than the viewport (avoiding horizontal
   scroll between 320 and 1920 px per Req 9.4). The ``auto-fill`` rule
   at ≥1024px lets very wide displays render four or more columns
   without us hardcoding a column count.
   -------------------------------------------------------------------------- */
.attendees-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 600px) {
  .attendees-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .attendees-grid {
    /* auto-fill so very wide displays use the available real estate
       without us hardcoding a 3-column ceiling. minmax(18rem, 1fr) is
       wide enough that an admin email never wraps mid-domain. */
    grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  }
}

.attendees-grid__item {
  /* Each <li> wraps a .cambry-card so the card surface treatment
     (defined in components.css) is shared. The list item itself
     contributes no styling — the cambry card is the visual. */
  margin: 0;
  padding: 0;
  list-style: none;
}

/* --------------------------------------------------------------------------
   Attendee_Card slot styling
   --------------------------------------------------------------------------
   The card surface itself (background, radius, shadow, hover lift) lives
   under .cambry-card in components.css. These rules style the slot content
   the cambry-card factory wraps in .cambry-card__header / __body /
   __actions / __feedback for the Attendees view specifically.
   -------------------------------------------------------------------------- */

/* Header slot — avatar (or placeholder) on the left, identity column
   on the right (display label + email + admin badge). */
.attendee-card__header {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
}

.attendee-card__avatar {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background-color: var(--color-primary);
  color: var(--color-text);
  font-family: 'Yantramanav', sans-serif;
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  /* Subtle border so the avatar circle reads cleanly against the
     card surface even when the placeholder fill matches a card edge. */
  border: 1px solid rgba(255, 255, 255, 0.08);
  /* No profile picture is available today (Req 9.3) — the placeholder
     letter is rendered via textContent inside the avatar element. */
  text-transform: uppercase;
  user-select: none;
}

.attendee-card__avatar img {
  /* Reserved for a future profile-picture treatment. Today the
     placeholder letter is the only visual; this rule makes sure that
     any future <img> insertion fills the circle cleanly. */
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

.attendee-card__identity {
  /* min-width: 0 lets long text (long emails) ellipsis-truncate via
     overflow: hidden on the children rather than blowing out the card
     width. */
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  flex: 1 1 auto;
}

.attendee-card__display-label {
  font-family: 'Yantramanav', sans-serif;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--color-text);
  line-height: 1.2;
  margin: 0;
  /* Allow long display labels (very long emails when name is empty)
     to truncate with an ellipsis so cards stay grid-aligned. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.attendee-card__email {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--color-text-muted);
  line-height: 1.2;
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.attendee-card__email:empty {
  display: none;
}

.attendee-card__admin-badge {
  align-self: flex-start;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background-color: var(--color-accent);
  color: var(--color-on-accent);
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-top: 0.2rem;
}

/* Body slot — home city. Renders a label-and-value pair in the slot
   below the header. When ``home_city`` is empty, the placeholder text
   reads "—" so the slot still occupies its grid row. */
.attendee-card__home-city {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.95rem;
  font-weight: 400;
  line-height: 1.4;
  color: var(--color-text-muted);
  margin: 0;
}

.attendee-card__home-city-label {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-right: 0.4rem;
}

.attendee-card__home-city-value {
  color: var(--color-text);
}

/* Activation hint — the entire card is keyboard-activatable so the
   card root gets the ``role="button"`` semantic from attendees.js.
   Focus-visible treatment makes the card visibly focused for keyboard
   users (the .cambry-card already has a :focus-within rule that lifts
   the card; this adds a pink-ring when the *card itself* is focused,
   not just a control inside it). */
.cambry-card[role="button"]:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

/* Feedback slot — inline error / success live region used by Save
   and Delete operations. The base .cambry-card__feedback rule in
   components.css already styles this; these are attendees-specific
   tone overrides for success and info states. */
.attendees-feedback--info {
  color: var(--color-text-muted);
}

.attendees-feedback--success {
  color: var(--color-success);
}

.attendees-feedback--error {
  color: var(--color-error);
}

/* --------------------------------------------------------------------------
   Inline edit form (Req 10.1)
   --------------------------------------------------------------------------
   Activated by clicking, tapping, or pressing Enter on a card. The
   form replaces the body and actions slots; the header stays in place
   so the user can see which attendee they are editing while typing.
   -------------------------------------------------------------------------- */
.attendee-edit-form {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  width: 100%;
}

.attendee-edit-form__field {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.attendee-edit-form__field--checkbox {
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  min-height: 44px;
}

.attendee-edit-form__label {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}

.attendee-edit-form__field-error {
  font-family: 'Yantramanav', sans-serif;
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--color-error);
  margin: 0;
  min-height: 0;
}

.attendee-edit-form__field-error:empty {
  display: none;
}

.attendee-edit-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem; /* 8px between adjacent controls (Req 14.3) */
  margin-top: 0.25rem;
}

/* --------------------------------------------------------------------------
   No-match state (Req 11.4)
   --------------------------------------------------------------------------
   Rendered when the search query is non-empty but no attendees match.
   Visually distinct from the registry-empty Empty_State (which uses
   the shared .cambry-empty primitive). The no-match panel sits inside
   the grid host, has its own light fill, and echoes the user's
   trimmed query verbatim.
   -------------------------------------------------------------------------- */
.attendees-no-match {
  grid-column: 1 / -1; /* span every column when nested in the grid */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
  padding: 1.25rem 1rem;
  background-color: var(--color-surface);
  border-radius: 12px;
  border: 1px dashed var(--color-primary);
  font-family: 'Yantramanav', sans-serif;
  color: var(--color-text);
}

.attendees-no-match__heading {
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-text);
  margin: 0;
}

.attendees-no-match__detail {
  font-size: 0.9rem;
  font-weight: 400;
  color: var(--color-text-muted);
  margin: 0;
  line-height: 1.4;
}

.attendees-no-match__query {
  /* Echo of the user's trimmed query verbatim. Wrapped in a slate
     pill so it visually reads as quoted user input. */
  display: inline-block;
  padding: 0.05rem 0.4rem;
  background-color: var(--color-bg);
  color: var(--color-text);
  border-radius: 4px;
  font-family: 'Menlo', 'Consolas', monospace;
  font-size: 0.85rem;
  font-weight: 500;
}

/* --------------------------------------------------------------------------
   Mobile spacing safety net (Req 14.1, 14.3)
   --------------------------------------------------------------------------
   At < 900 CSS px, every adjacent enabled control must keep an 8px
   minimum gap. The toolbar row, card actions, and edit-form actions
   already use ``gap: 0.5rem`` (= 8px); this block reinforces the
   row-gap when the controls wrap onto multiple lines on narrow
   screens.
   -------------------------------------------------------------------------- */
@media (max-width: 899px) {
  .attendees-toolbar__row,
  .attendees-add-form,
  .attendee-edit-form__actions {
    row-gap: 0.5rem;
    column-gap: 0.5rem;
  }
}
