/**
 * F-106 — Contextual Footer (Dynamic Action Bar)
 *
 * Sticky bottom bar that anchors iOS rubber-band overscroll AND houses
 * page-specific primary actions. 5 modes (home/browse/task/picker/lens).
 *
 * Locked principles:
 *   - Always opaque (rubber-band anchoring requirement)
 *   - 800px max-width content (var(--content-max))
 *   - Anchors > Actions > Context priority (context truncates first)
 *   - Safe-area-inset-bottom respected
 *   - Light + dark theme support
 *   - prefers-reduced-motion respected (pulse → static glow)
 *
 * Class system: BEM. Prefix `cf__` for elements, `cf--` for state.
 * z-index: 50 (below modals, above content).
 */

/* ── Container ─────────────────────────────────────────────────────────── */

.contextual-footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 50;

  /* Opaque background — required for iOS overscroll anchoring */
  background: var(--bg-secondary);
  border-top: 1px solid var(--border);

  /* Safe-area extension: footer body + iPhone home-bar inset */
  padding-bottom: env(safe-area-inset-bottom, 0px);

  /* Reasonable shadow above so content scrolling under has visual edge */
  box-shadow: 0 -1px 0 var(--border);
}

/* Production safety: hide the footer when the component hasn't enhanced it
 * (flag OFF in production). Without this, prod users see a blank 64px fixed
 * bar at the bottom of every wired page. enhance() fills .cf__inner; until
 * then, :empty hides it. */
.contextual-footer:empty {
  display: none;
}

.contextual-footer__inner,
.cf__inner {
  /* 800px-constrained content row, centred. Height matches the unified header
   * (min-height: 48px in css/unified-header-3col-fixed.css) so top + bottom
   * chrome are visually balanced. 44px touch targets still fit (anchors use
   * min-width/min-height: 44px). The footer's TOTAL height then = 48px + the
   * env(safe-area-inset-bottom) extension below, which is intentional system
   * chrome and matches iOS native UITabBar conventions. */
  max-width: var(--content-max, 800px);
  margin: 0 auto;
  height: 48px;
  padding: 0 var(--space-sm, 8px);
  display: flex;
  align-items: center;
  gap: var(--space-sm, 8px);
}

/* ── Anchor zones (left + right edges) ─────────────────────────────────── */

.cf__anchor-zone {
  flex: 0 0 auto;
  width: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.cf__anchor-zone--left  { justify-content: flex-start; padding-left: 4px; }
.cf__anchor-zone--right { justify-content: flex-end;   padding-right: 4px; }

/* Two-anchor left zone (task mode with back-to-subject + home) */
.cf__anchor-zone--double {
  width: auto;
  gap: 2px;
}
.cf__anchor-zone--double .cf__anchor {
  /* Tighten visuals; 44px touch target preserved via min-width/min-height. */
  padding: 6px;
}

/* When F-106 is on, the learn-task page rating buttons live in the footer.
 * Hide the in-content .learn-card-footer to avoid duplication. The contextual
 * footer's :empty rule handles the OFF case — when the footer renders nothing,
 * it's hidden and .learn-card-footer remains visible as the fallback. */
body:has(.contextual-footer:not(:empty)) .learn-card-footer {
  display: none;
}
/* Page counter (book icon + "X / Y") in the top stats bar duplicates the
 * footer's "Learn  X / Y". Hide via CSS so the element stays in DOM —
 * learn-mode.js still updates its textContent and our MutationObserver
 * still picks up the change to drive the footer counter. */
body:has(.contextual-footer:not(:empty)) .learn-stats-left > .learn-stat-item {
  display: none;
}

.cf__anchor {
  /* 44px touch target preserved via min-width/min-height; visual padding
   * tightened to 8px so the anchor doesn't dominate the 50px bar. */
  min-width: 44px;
  min-height: 44px;
  padding: 8px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--text-secondary);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 150ms ease, background 150ms ease, transform 100ms ease;
}

/* Uniform anchor SVG sizing — Icons.get() emits inline width/height for its
 * lucide icons, but `ctx.backIconSvg` (e.g. SubjectConfig icons) doesn't. This
 * rule normalises both cases so the back anchor never renders at default 150px. */
.cf__anchor svg { width: 22px; height: 22px; pointer-events: none; }

.cf__anchor:hover  { color: var(--text-primary); background: var(--bg-card); }
.cf__anchor:active { transform: scale(0.96); }
.cf__anchor:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.cf__anchor--placeholder {
  /* Reserves the same space when an anchor is suppressed (Home on home page,
   * Progress on progress page) so the centre zone doesn't reflow. */
  width: 44px;
  height: 44px;
}

/* ── Centre zone (context + actions) ───────────────────────────────────── */

.cf__zone {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm, 8px);
  min-width: 0; /* allow text-overflow to fire on context */
}

.cf__context {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--font-sm, 13px);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 6px;
}

.cf__context-label   { color: var(--text-primary); font-weight: 600; }
.cf__context-stats   { color: var(--text-secondary); }
.cf__context-progress {
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.cf__context-icon {
  display: inline-flex;
  align-items: center;
  color: var(--text-primary);
}
.cf__context-icon svg { display: block; }

/* Actions claim space; context yields */
.cf__actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
}

/* ── Action buttons ────────────────────────────────────────────────────── */

.cf__action {
  min-height: 44px;
  padding: 8px 14px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg-card);
  color: var(--text-primary);
  font-size: var(--font-sm, 13px);
  font-weight: 600;
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease, transform 100ms ease;
  white-space: nowrap;
}

.cf__action:hover:not(:disabled) {
  border-color: var(--border-light);
  background: var(--bg-primary);
}
.cf__action:active:not(:disabled) { transform: scale(0.97); }
.cf__action:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.cf__action--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #ffffff;
}
.cf__action--primary:hover:not(:disabled) {
  background: var(--accent-hover);
  border-color: var(--accent-hover);
}

.cf__action--secondary {
  /* default styling above */
}

/* Icon-only action button — bare SVG, NO button chrome.
 * Just the icon: outlined by default, filled when selected.
 * 44×44 touch target preserved (non-negotiable) but invisible —
 * no border, no background, no chip.
 *
 * Per-action colour comes from --cf-action-color (set inline by the page
 * via action.color). Falls back to --text-secondary when absent.
 */
.cf__action--icon {
  min-width: 44px;
  min-height: 44px;
  padding: 8px;
  border: none;
  background: transparent;
  color: var(--cf-action-color, var(--text-secondary));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  transition: color 150ms ease;
}
.cf__action--icon svg {
  display: block;
  fill: none;
  stroke: currentColor;
  transition: fill 150ms ease;
  /* iOS: prevent SVG path/line elements from being the click target.
   * Without this, e.target on an icon tap is an SVGPathElement, which in
   * some iOS/WKWebView contexts fails the target.closest() guard and the
   * click delegation silently no-ops. The button element itself receives
   * the event instead, which always has .closest(). */
  pointer-events: none;
}
.cf__action--icon:hover:not(:disabled) {
  background: transparent;
  border: none;
  filter: brightness(0.85);
}
.cf__action--icon:active:not(:disabled) { transform: scale(0.92); }

/* Selected — SVG fills with the action colour; stroke flips to a
 * theme-aware contrast (dark slate in light mode, light slate in dark mode)
 * so the icon stays readable on top of the coloured fill. Stroke width
 * thins from 2 (default) to 1.5 — the fill carries the visual weight,
 * the outline just adds definition. */
.cf__action--icon[data-cf-selected="true"] svg {
  fill: currentColor;
  stroke: var(--text-primary);
  stroke-width: 0.5;
}

.cf__action:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ── Mode: home — streak/XP context + daily tiles ──────────────────────── */

.cf__context--home {
  /* Status surface: text-only, must share space with anchors. flex: 1 1 auto
   * lets the centre zone shrink so the focus chip truncates rather than
   * overlapping the right Progress anchor on narrow mobile viewports. */
  flex: 1 1 auto;
  min-width: 0;
  gap: 10px;
}

.cf__stat {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--text-secondary);
  /* Match home-counter — 12px keeps the streak prefix visually balanced
   * with the counter text it sits beside */
  font-size: var(--font-xs, 12px);
  font-variant-numeric: tabular-nums;
}
.cf__stat--streak svg { color: #f59e0b; }  /* flame amber */
.cf__stat--xp     svg { color: #eab308; }  /* zap gold */
.cf__stat-value { font-weight: 700; color: var(--text-primary); }

.cf__tiles {
  display: flex;
  gap: 8px;
}

.cf__tile {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg-card);
  color: var(--text-primary);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 100ms ease, border-color 150ms ease;
}
.cf__tile:hover  { border-color: var(--accent); }
.cf__tile:active { transform: scale(0.94); }
.cf__tile--played {
  opacity: 0.45;
}
.cf__tile--played::after {
  /* Subtle "done" indicator — small dot top-right */
  content: '';
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #22c55e;
  margin-left: 28px;
  margin-top: -28px;
}

.cf__tiles-empty {
  font-size: var(--font-sm, 13px);
  color: var(--text-secondary);
  font-style: italic;
}

/* ── F-106 home mode — status text (no emojis, SVGs only) ──────────────── */

.cf__home-sep {
  color: var(--text-secondary);
  margin: 0 4px;
  opacity: 0.6;
}

.cf__home-counter,
.cf__home-done,
.cf__home-celebrate {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* Visual-weight knob: var(--font-xs, 12px) instead of --font-sm so the home
   * footer status text feels lighter without shrinking the bar height. */
  font-size: var(--font-xs, 12px);
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}

.cf__home-counter {
  color: var(--text-primary);
  font-weight: 600;
}

.cf__home-counter--urgent {
  color: #f59e0b;  /* amber — 1 thing left to keep streak */
  font-weight: 700;
}

.cf__home-done {
  color: #22c55e;  /* green — daily target hit */
  font-weight: 700;
}
.cf__home-done svg { color: #22c55e; }

.cf__home-celebrate {
  color: var(--text-primary);
  font-weight: 600;
}

.cf__home-focus {
  background: transparent;
  border: 1px dashed var(--border-light);
  border-radius: 8px;
  padding: 4px 10px;
  font-size: var(--font-xs, 12px);
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
  transition: background 150ms ease, border-color 150ms ease;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  /* min-width:0 + max-width via flex so the chip TRUNCATES inside the cf__zone
   * rather than overflowing past the right anchor on narrow viewports */
  min-width: 0;
  flex-shrink: 1;
  max-width: 100%;
}

/* ── F-106 browse search-active state ──────────────────────────────────── */
.cf__search-query {
  font-weight: 700;
  color: var(--text-primary);
  font-size: var(--font-xs, 12px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 50%;
}
.cf__home-focus:hover {
  background: var(--bg-card);
  border-color: var(--accent);
}
.cf__home-focus:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ── Mode: task — games chip ───────────────────────────────────────────── */

.cf__games-chip {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg-card);
  color: var(--text-primary);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 100ms ease, border-color 150ms ease, box-shadow 200ms ease;
  position: relative;
}
.cf__games-chip:hover  { border-color: var(--accent); }
.cf__games-chip:active { transform: scale(0.94); }

/* ── Mode: lens — step indicator + progress bar ───────────────────────── */

.cf__step {
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.cf__progress-bar {
  display: inline-block;
  width: 80px;
  height: 6px;
  background: var(--bg-card);
  border-radius: 3px;
  overflow: hidden;
  border: 1px solid var(--border);
  margin-left: 6px;
}
.cf__progress-fill {
  display: block;
  height: 100%;
  background: var(--accent);
  transition: width 250ms ease;
}

/* ── Pulse animation (intervention nudge) ──────────────────────────────── */

@keyframes cf-pulse {
  0%   { box-shadow: 0 0 0 0   rgba(37, 99, 235, 0.55); }
  60%  { box-shadow: 0 0 0 10px rgba(37, 99, 235, 0); }
  100% { box-shadow: 0 0 0 0   rgba(37, 99, 235, 0); }
}

.cf--pulsing {
  animation: cf-pulse 1.2s ease-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .cf--pulsing {
    animation: none;
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.55);
  }
  .cf__progress-fill {
    transition: none;
  }
}

/* ── Mobile cramped behaviour ──────────────────────────────────────────── */

@media (max-width: 380px) {
  .cf__inner { padding: 0 4px; }

  /* Home mode: collapse stat values to icons only when space tight */
  .cf__context--home .cf__stat-value { display: none; }

  /* Hide context-label on browse/picker if it'd push actions off-screen */
  .cf__context--browse .cf__context-stats,
  .cf__context--picker .cf__context-stats { display: none; }
}

/* ── Page padding utility ──────────────────────────────────────────────── */
/* Pages that mount the footer should add `.page-with-footer` to their
 * main content container so the last item isn't hidden behind the bar. */
.page-with-footer {
  padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 16px);
}

/* ── Light theme overrides ─────────────────────────────────────────────── */
[data-theme="light"] .contextual-footer {
  background: var(--bg-secondary);
  border-top-color: var(--border);
  box-shadow: 0 -1px 0 var(--border);
}

[data-theme="light"] .cf__action--primary {
  color: #ffffff;
}
