/* ══════════════════════════════════════════════════════════════════════════
   v14 additions — content-rich cards, quick actions, dashboard home layout
   v17 — SmartCardVisuals default flipped to true, plus fixes to several of
   the rules below (see the v17 comments at each one for what changed and
   why): centered/category-tinted emoji fallback, theme-aware video
   gradient, real-thumbnail support, responsive card height, favourite
   button position, broken-image fallback.
   See CHANGELOG.md and IMPLEMENTATION_NOTES.md for the rationale.
   A pack that explicitly sets "smartCardVisuals": false still renders
   byte-for-byte as before — none of this applies without that flag.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── CardVisual (smart image/video/map/emoji hierarchy) ─────────────────── */

/* When a card's visual is "smart" (Features.SmartCardVisuals), the card
   switches from its usual row layout (small icon + text beside it) to a
   column layout with the visual spanning the full width up top — the
   layout change a "dominant" image/video/map needs actually lives on the
   *card*, not just the icon slot, so it's scoped with :has() rather than
   requiring a second class on the outer element. */
.activity-card:has(.activity-card__emoji--smart) {
  flex-direction: column;
  padding: 0;
  overflow: hidden;
  gap: 0;
}
/* v17: a fixed pixel height cropped very differently depending on how wide
   the card itself ended up (220px mosaic column vs. a much wider desktop
   grid column) — a photo that looked like a proper hero banner on mobile
   became a thin panoramic strip on desktop. aspect-ratio scales the crop
   with the card's own width at every breakpoint instead of fighting it.
   The mosaic "featured" override below (height:auto + min-height + flex)
   already takes priority in that specific context, so this only changes
   the standard, non-featured case. */
.activity-card:has(.activity-card__emoji--smart) > .activity-card__emoji--smart {
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border-radius: 0;
}
.activity-card:has(.activity-card__emoji--smart) > .activity-card__body {
  padding: var(--spacing-md, 16px);
}
/* v17 fix: this used to jump to top:132px specifically to "float over the
   bottom edge of the visual" — a button straddling the seam between a photo
   and the plain body background below it, half on each. ProfileCardVariant
   never needed a special case like this: its favourite button just sits at
   the image's own top-right corner, same as the card's default (non-smart)
   position already does. Removing the override brings this in line with
   that — and with the near-universal "favourite anchored to the top corner
   of the photo" convention (Airbnb, Pinterest, etc.). */

.card-visual {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.card-visual--image {
  object-fit: cover;
}
.card-visual--video,
.card-visual--map {
  flex-direction: column;
  gap: var(--spacing-xs, 6px);
  color: white;
  text-align: center;
  padding: var(--spacing-sm, 10px);
}
/* v17: was a flat hardcoded navy (#2b2b3d/#14141f) — every video card looked
   identical regardless of pack theme, unlike the map gradient right below it
   which already pulled from --color-primary. Kept deliberately dark (still
   needs to hold contrast for the white play icon/label, and stay visually
   distinct from the lighter, more saturated map gradient) but now tints
   toward the pack's own primary color instead of an unrelated fixed navy. */
.card-visual--video {
  position: relative;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--color-primary, #453FE9) 50%, #1a1a2e),
    #101018);
}
.card-visual--map {
  background: linear-gradient(135deg, var(--color-primary-light, #6B65F0), var(--color-primary, #453FE9));
}

/* v17: real cached thumbnail (ContentBlock.ThumbnailSrc — see
   YoutubeThumbnailService) rendered as a cover image behind the play
   button, when one has been fetched at pack-build time. The gradient above
   stays as the background either way: it shows through instantly while the
   lazy-loaded thumbnail is still fetching, and it's what renders if the
   pack never got one (old pack, or the fetch failed) or if the image
   404s. The scrim keeps the play icon/label legible over a thumbnail of
   any brightness — video thumbnails are often much lighter than the
   gradient they replace. */
.card-visual__video-thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}
.card-visual--video-has-thumb::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.32);
  z-index: 0;
}
.card-visual__play,
.card-visual__label {
  position: relative;
  z-index: 1;
}
.card-visual__play {
  width: 44px;
  height: 44px;
}
.card-visual__pin {
  width: 28px;
  height: 28px;
}
.card-visual__label {
  font-size: var(--font-size-xs, 0.75rem);
  font-weight: 700;
  max-width: 90%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* v17 fix: this used to be a bare `@Activity.Emoji` text node with no
   wrapping element at all, so it inherited only the base
   .activity-card__emoji rule's text-align:center (horizontal only) — no
   vertical centering, no sizing of its own. In a 160px-tall (now
   aspect-ratio-based) box that's most of the card's activities (anything
   without a photo/video/map), it rendered as a small glyph adrift in an
   otherwise-empty rectangle. Wrapping it in the same .card-visual flex box
   the other three kinds already use centers it properly; the category tint
   (premium.css B1) and glow below make the fallback look like a deliberate
   design choice instead of a placeholder that didn't load. Falls back to a
   flat neutral background for activities with no category set. */
.card-visual--emoji {
  font-size: 2.5rem;
  background: var(--color-surface-alt, #f3f4f6);
}

/* Broken hero-image edge case (see CardVisual.razor's onerror handler): this
   used to add the class below with no matching rule, so a 404'd image left
   a completely empty box behind — no color, no emoji, nothing. A neutral
   background at least reads as an intentional empty state. */
.activity-card__emoji--visual-fallback {
  background: var(--color-surface-alt, #f3f4f6);
}

/* ── ProfileCardVariant (portrait + name/role + quick contact actions) ──── */

.profile-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  border-radius: var(--border-radius-lg, 18px);
  border: var(--card-border-width, 1.5px) solid var(--color-border);
  background: var(--color-surface);
  overflow: hidden;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  box-shadow: var(--card-shadow);
  transition: box-shadow 180ms ease, transform 120ms ease, border-color 180ms ease;
  animation: cardIn 0.3s cubic-bezier(0.34, 1.1, 0.64, 1) both;
}
.profile-card:hover {
  box-shadow: var(--card-shadow-hover);
  transform: translateY(var(--card-hover-translate-y, -2px));
  border-color: var(--color-primary);
}
.profile-card:active { transform: scale(0.98); }
.profile-card--done  { opacity: 0.6; }

.profile-card__portrait {
  position: relative;
  width: 100%;
  height: 140px;
  background: var(--color-surface-alt, #f3f4f6);
  display: flex;
  align-items: center;
  justify-content: center;
}
.profile-card__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.profile-card__emoji {
  font-size: 2.5rem;
}
.profile-card__badge {
  position: absolute;
  bottom: var(--spacing-sm, 10px);
  left: var(--spacing-sm, 10px);
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface);
  box-shadow: 0 1px 4px rgba(0,0,0,0.15);
}
.profile-card__fav {
  position: absolute;
  top: var(--spacing-sm, 10px);
  right: var(--spacing-sm, 10px);
  z-index: 2;
  background: var(--color-surface);
  border: 1.5px solid var(--color-border);
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--color-text-muted);
  box-shadow: 0 1px 4px rgba(0,0,0,0.08);
  transition: all var(--transition-fast, 150ms ease);
}
.profile-card__fav--active { color: #e04a6a; border-color: #e04a6a; background: rgba(224,74,106,0.08); }
.profile-card__fav:hover   { transform: scale(1.06); }

.profile-card__body {
  padding: var(--spacing-md, 16px);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.profile-card__name {
  margin: 0;
  font-family: var(--font-family-heading, system-ui);
  font-size: var(--font-size-md, 1rem);
  font-weight: 800;
  color: var(--color-text);
}
.profile-card__role {
  margin: 0;
  font-size: var(--font-size-sm, 0.875rem);
  color: var(--color-text-muted);
}
.profile-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-xs, 6px);
  margin-top: var(--spacing-sm, 10px);
}
.profile-card__action-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--radius-sm, 6px);
  border: 1.5px solid var(--color-border);
  background: var(--color-surface-alt, #f3f4f6);
  color: var(--color-text);
  font-size: var(--font-size-xs, 0.75rem);
  font-weight: 700;
  text-decoration: none;
  transition: all var(--transition-fast, 150ms ease);
}
.profile-card__action-btn:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

/* ── QuickActionBar ───────────────────────────────────────────────────────
   Deliberately styled as a lighter-weight sibling to .panic-btn — a row of
   these usually appears *alongside* the panic button, so they shouldn't
   visually compete with it for attention. */

.quick-action-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-sm, 10px);
  padding: 0 var(--spacing-lg, 24px) var(--spacing-md, 16px);
}
.quick-action-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  border-radius: var(--border-radius-lg, 18px);
  border: 1.5px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
  font-family: var(--font-family-heading, system-ui);
  font-size: var(--font-size-sm, 0.875rem);
  font-weight: 700;
  transition: transform 120ms ease, border-color 180ms ease, box-shadow 180ms ease;
}
.quick-action-btn:hover  { border-color: var(--color-primary); box-shadow: var(--card-shadow); }
.quick-action-btn:active { transform: scale(0.96); }
.quick-action-btn__icon  { font-size: 1.1rem; line-height: 1; }

.quick-action-btn--calm {
  background: var(--color-surface);
}
.quick-action-btn--urgent {
  background: var(--color-danger, #e04a4a);
  border-color: var(--color-danger, #e04a4a);
  color: var(--color-text-on-primary, white);
}
.quick-action-btn--accent {
  background: var(--color-accent, #FF8A3D);
  border-color: var(--color-accent, #FF8A3D);
  color: var(--color-text-on-primary, white);
}

/* ── DashboardHome (button-grid alternative landing screen) ──────────────── */

.dashboard-home {
  padding: var(--spacing-md, 16px) var(--spacing-lg, 24px) var(--spacing-xl, 32px);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg, 24px);
}
.dashboard-home__section-title {
  margin: 0 0 var(--spacing-sm, 10px);
  font-family: var(--font-family-heading, system-ui);
  font-size: var(--font-size-sm, 0.875rem);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.dashboard-home__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: var(--spacing-sm, 10px);
}
.dashboard-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 96px;
  padding: var(--spacing-md, 16px) var(--spacing-sm, 10px);
  border-radius: var(--border-radius-lg, 18px);
  border: 1.5px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
  text-align: center;
  transition: transform 120ms ease, border-color 180ms ease, box-shadow 180ms ease;
  box-shadow: var(--card-shadow);
}
.dashboard-tile:hover  { border-color: var(--color-primary); box-shadow: var(--card-shadow-hover); }
.dashboard-tile:active { transform: scale(0.96); }
.dashboard-tile__icon  { font-size: 1.75rem; line-height: 1; }
.dashboard-tile__label {
  font-family: var(--font-family-heading, system-ui);
  font-size: var(--font-size-xs, 0.75rem);
  font-weight: 700;
  line-height: 1.2;
}
.dashboard-tile--calm   { background: var(--color-surface); }
.dashboard-tile--urgent { background: var(--color-danger, #e04a4a); border-color: var(--color-danger, #e04a4a); color: var(--color-text-on-primary, white); }
.dashboard-tile--accent { background: var(--color-accent, #FF8A3D); border-color: var(--color-accent, #FF8A3D); color: var(--color-text-on-primary, white); }
.dashboard-tile--category { background: var(--color-surface-alt, #f3f4f6); }

.dashboard-home__browse-all {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 12px;
  border-radius: var(--border-radius-lg, 18px);
  border: 1.5px dashed var(--color-border);
  background: transparent;
  color: var(--color-text-muted);
  font-family: var(--font-family-heading, system-ui);
  font-size: var(--font-size-sm, 0.875rem);
  font-weight: 700;
  cursor: pointer;
}
.dashboard-home__browse-all:hover { border-color: var(--color-primary); color: var(--color-primary); }
