/* assets/games/wordfinder.css — v1.6
 * v1.6 (2026-06-19): completion overlay was cut off at top + bottom on
 * short viewports — `align-items:center` with no overflow scroll. Added
 * `overflow-y:auto` and `align-items: safe center` so the card scrolls
 * within the overlay when content > viewport, anchored at the top so the
 * headline stays visible.
 * v1.5 (2026-06-18): added .wf-mobile-list-hint rules — mobile-only pill
 * affordance above the grid pointing to the word list below the fold.
 * Plus scroll-behavior:smooth on body.wf-page for the anchor jump.
 * v1.0
 * ============================================================================
 * Word Finder framework styles, structurally parallel to crossword.css.
 *
 * Themed via the SAME CSS variables crossword.css consumes (--xword-*) so
 * assets/games/state-themes.css applies to both games unchanged through a
 * body.state-{slug} class. :root fallbacks below duplicate crossword.css's
 * defaults because the two stylesheets never load on the same page.
 *
 * Zero coupling to sim chrome / sim-shared.css. Lives on the standalone
 * /games/{state}-wordfinder pages. Mobile-first; works at 375px.
 *
 * Touch: the letter grid is a continuous drag-select surface (touch-action:
 * none) — individual cells are below 44px by the nature of a 14×14 board,
 * but no cell is a discrete tap target. All discrete controls (toolbar
 * buttons, overlay actions) meet the 44px minimum.
 *
 * Author: Earn-Points framework (PR feat/wordfinder-md-prototype, WF-2).
 * ==========================================================================*/

:root {
  --xword-primary: #1f2937;
  --xword-accent: #2563eb;
  --xword-bg-tint: #f9fafb;
  --xword-border: #e5e7eb;
  --xword-text: #111827;
  --xword-cell-revealed: #d97706;
  --xword-cell-active: #fde68a;
  --xword-cell-in-word: #fff7e0;
}

body.wf-page {
  margin: 0;
  padding: 0;
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  background: var(--xword-bg-tint);
  color: var(--xword-text);
  min-height: 100vh;
}

.wf-shell {
  max-width: 1080px;
  margin: 0 auto;
  padding: 16px;
}

.wf-topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 12px;
  padding-bottom: 12px;
  border-bottom: 2px solid var(--xword-border);
}
.wf-topbar h1 {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--xword-primary);
}
.wf-topbar .wf-desc {
  font-size: 0.85rem;
  color: #6b7280;
}
.wf-topbar .wf-back {
  font-size: 0.9rem;
  color: var(--xword-primary);
  text-decoration: none;
  font-weight: 600;
  /* discrete control — keep the hit area >= 44px tall */
  padding: 10px 4px;
}
.wf-topbar .wf-back:hover { text-decoration: underline; }

.wf-statbar {
  display: flex;
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
  font-size: 0.92rem;
  margin-bottom: 12px;
}
.wf-stat {
  background: #fff;
  border: 1px solid var(--xword-border);
  padding: 6px 12px;
  border-radius: 9999px;
  font-weight: 600;
  color: var(--xword-text);
}
.wf-stat .wf-stat-label {
  color: #6b7280;
  font-size: 0.78rem;
  margin-right: 6px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.wf-stat-score { border-color: var(--xword-primary); }

.wf-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  scroll-behavior: smooth;
}
@media (min-width: 900px) {
  .wf-layout {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  }
}
/* Smooth-scroll the page so the mobile "tap to see list" anchor glides
   to #wf-word-list instead of jump-cutting. (Matthew 2026-06-18.) */
body.wf-page {
  scroll-behavior: smooth;
}

/* Mobile-only "📋 N hidden words to find — tap to see the list ↓"
   affordance. On <900px the .wf-side word list stacks below the grid;
   first-time players had no signal that a word list existed until they
   scrolled past the grid. This pill sits above the grid as an
   unmistakable pointer + smooth-scroll anchor to #wf-word-list. CSS
   hides it on the 2-column desktop layout (≥900px) where the word
   list is already visible next to the board. */
.wf-mobile-list-hint {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: var(--xword-cell-active, #fef3c7);
  border: 1px solid var(--xword-primary, #c49a27);
  border-radius: 8px;
  color: var(--xword-primary, #c49a27);
  font-weight: 700;
  font-size: 0.9rem;
  text-decoration: none;
  text-align: center;
  justify-content: center;
  cursor: pointer;
}
.wf-mobile-list-hint:hover,
.wf-mobile-list-hint:focus-visible {
  background: var(--xword-accent, #fff8e1);
  outline: 2px solid var(--xword-primary, #c49a27);
  outline-offset: 2px;
}
.wf-mlh-icon { font-size: 1.1rem; }
.wf-mlh-arrow {
  font-size: 1.15rem;
  font-weight: 900;
  animation: wf-mlh-bob 1.6s ease-in-out infinite;
}
@keyframes wf-mlh-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(3px); }
}
@media (prefers-reduced-motion: reduce) {
  .wf-mlh-arrow { animation: none; }
}
/* Hidden on the 2-column desktop layout — the word list is already visible. */
@media (min-width: 900px) {
  .wf-mobile-list-hint { display: none; }
}

.wf-board-wrap {
  background: #fff;
  border: 2px solid var(--xword-border);
  border-radius: 8px;
  padding: 8px;
  overflow-x: auto;
}

table.wf-grid {
  border-collapse: collapse;
  margin: 0 auto;
  table-layout: fixed;
  /* Continuous drag-select surface: suppress scrolling/zoom gestures so
     pointermove tracks the finger (mouse + touch via Pointer Events). */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}
table.wf-grid td {
  width: 30px;
  height: 30px;
  border: 1px solid #e2e8f0;
  text-align: center;
  vertical-align: middle;
  font-weight: 600;
  font-size: 1rem;
  background: #fff;
  cursor: pointer;
  text-transform: uppercase;
  color: var(--xword-text);
}
@media (max-width: 500px) {
  table.wf-grid td {
    /* 14 columns inside 375–500px viewports */
    width: calc((100vw - 60px) / 14);
    height: calc((100vw - 60px) / 14);
    font-size: 0.78rem;
  }
}
/* Matthew 2026-06-11 (landscape clip): in landscape on a phone the viewport
   height is the limiting dimension (e.g. 812×375 iPhone), but the cell rules
   above only key off viewport WIDTH. The grid ends up wider than tall but
   taller than the visible viewport, so the bottom rows get clipped. Cap the
   cell size by the smaller of (width-derived, height-derived) so the whole
   board always fits. ~220px reserved for the page header + game header +
   toolbar above + a little breathing room below. Uses dvh (dynamic vh) so
   iOS Safari's bottom toolbar is accounted for. */
@media (orientation: landscape) and (max-height: 600px) {
  table.wf-grid td {
    width:  min(calc((100vw - 80px) / 14), calc((100dvh - 220px) / 14));
    height: min(calc((100vw - 80px) / 14), calc((100dvh - 220px) / 14));
    font-size: clamp(0.55rem, calc((100dvh - 220px) / 14 * 0.5), 1rem);
  }
}
table.wf-grid td.wf-sel {
  background: var(--xword-cell-active);
  outline: 1px solid var(--xword-primary);
  outline-offset: -1px;
}
table.wf-grid td.wf-found {
  background: var(--xword-accent);
  color: var(--xword-primary);
  font-weight: 800;
}
table.wf-grid td.wf-revealed {
  background: var(--xword-cell-in-word);
  color: var(--xword-cell-revealed);
  font-weight: 800;
}
table.wf-grid td.wf-flash {
  animation: wf-flash-pulse 0.5s ease-in-out 4;
}
@keyframes wf-flash-pulse {
  0%, 100% { background: #fff; }
  50% { background: var(--xword-cell-active); outline: 2px solid var(--xword-primary); outline-offset: -2px; }
}

/* Word list */
.wf-side {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.wf-wordlist-section {
  background: #fff;
  border: 1px solid var(--xword-border);
  border-radius: 6px;
  padding: 10px 12px;
}
.wf-wordlist-section h2 {
  margin: 0 0 6px;
  font-size: 0.92rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--xword-primary);
  border-bottom: 1px solid var(--xword-border);
  padding-bottom: 4px;
}
.wf-wordlist-section ul {
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: 0.88rem;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px 10px;
}
/* Matthew 2026-06-11 (portrait reinforcement, follow-up to the bleed fix
   in the previous commit): two narrow half-columns can't host long state
   terms + a "math/MD/VA" tag on the smallest viewports — the second
   column's content was pushed past the right edge. Collapse to a single
   column under ~420px so terms always sit inside the container. */
@media (max-width: 419px) {
  .wf-wordlist-section ul { grid-template-columns: 1fr; }
}
@media (min-width: 900px) {
  .wf-wordlist-section ul { grid-template-columns: 1fr; }
}
.wf-word {
  padding: 4px 6px;
  border-radius: 4px;
  line-height: 1.35;
  /* Mobile bleed fix (Matthew 2026-06-11): grid children default to
     min-width:auto which lets long terms (e.g. PROTHONOTARY) push
     past their half-width cell on narrow viewports. Allow shrink +
     mid-token wrap so the list stays inside its container. Formula
     white-space override lives at the .wf-word-formula rule below. */
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.wf-word .wf-word-term {
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--xword-primary);
}
.wf-word .wf-word-tag {
  display: inline-block;
  margin-left: 6px;
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #6b7280;
  border: 1px solid var(--xword-border);
  border-radius: 9999px;
  padding: 0 6px;
  vertical-align: middle;
}
.wf-word.found .wf-word-term {
  text-decoration: line-through;
  color: #9ca3af;
}
.wf-word .wf-word-def {
  display: block;
  font-size: 0.78rem;
  color: #6b7280;
  margin-top: 1px;
}
.wf-word .wf-word-formula {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.74rem;
  color: var(--xword-primary);
  /* Mobile bleed fix (Matthew 2026-06-11): was `white-space: nowrap` —
     long formulas overflowed their half-width grid cell on narrow
     viewports. Wrap instead. Pairs with .wf-word { min-width: 0 }. */
  white-space: normal;
}

/* Found-card — the teaching moment (definition + formula on find) */
.wf-found-card {
  display: none;
  background: #fff;
  border: 1px solid var(--xword-border);
  border-left: 5px solid var(--xword-accent);
  border-radius: 6px;
  padding: 12px 14px;
}
.wf-found-card.visible { display: block; }
.wf-found-card .wf-found-card-term {
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--xword-primary);
  margin-bottom: 4px;
}
.wf-found-card .wf-found-card-def {
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--xword-text);
}
.wf-found-card .wf-found-card-formula {
  margin-top: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--xword-primary);
  background: var(--xword-bg-tint);
  border: 1px dashed var(--xword-border);
  border-radius: 4px;
  padding: 4px 8px;
  display: inline-block;
}
.wf-found-card .wf-found-card-source {
  margin-top: 6px;
  font-size: 0.72rem;
  color: #9ca3af;
}

/* Toolbar — discrete controls meet the 44px touch minimum */
.wf-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0;
}
.wf-toolbar button {
  background: #fff;
  border: 1.5px solid var(--xword-primary);
  color: var(--xword-primary);
  min-height: 44px;
  padding: 8px 16px;
  border-radius: 9999px;
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  font-family: inherit;
}
.wf-toolbar button:hover,
.wf-toolbar button:focus {
  background: var(--xword-primary);
  color: #fff;
  outline: 2px solid var(--xword-accent);
  outline-offset: 2px;
}
.wf-toolbar button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  background: #fff;
  color: var(--xword-primary);
  outline: none;
}
.wf-toolbar button.wf-btn-danger {
  border-color: #b91c1c;
  color: #b91c1c;
}
.wf-toolbar button.wf-btn-danger:hover:not(:disabled),
.wf-toolbar button.wf-btn-danger:focus:not(:disabled) {
  background: #b91c1c;
  color: #fff;
}

/* Completion overlay
 * Matthew 2026-06-19 (MD playtest): on short viewports (mobile landscape,
 * short phones) the card was cut off at top AND bottom — `align-items:
 * center` with no scroll meant tall content overflowed both ends out of
 * view. Two fixes:
 *   1. overflow-y:auto so the overlay scrolls when content > viewport
 *   2. `align-items: safe center` — the modern Flexbox keyword that
 *      anchors at the start when content overflows the container, keeping
 *      the headline visible and the bottom reachable by scroll. Falls
 *      back to `center` on browsers that don't support `safe`. */
.wf-done-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: none;
  align-items: center;
  align-items: safe center;
  justify-content: center;
  z-index: 9000;
  padding: 16px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.wf-done-overlay.visible { display: flex; }
.wf-done-card {
  background: #fff;
  border-radius: 12px;
  padding: 24px 28px;
  max-width: 420px;
  width: 100%;
  text-align: center;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
  border-top: 6px solid var(--xword-primary);
}
.wf-done-card h2 {
  margin: 0 0 8px;
  font-size: 1.4rem;
  color: var(--xword-primary);
}
.wf-done-sub {
  color: #6b7280;
  font-size: 0.9rem;
}
.wf-done-stats {
  display: flex;
  justify-content: center;
  gap: 16px;
  margin: 14px 0;
  flex-wrap: wrap;
}
.wf-done-stat {
  background: var(--xword-bg-tint);
  border: 1px solid var(--xword-border);
  border-radius: 8px;
  padding: 10px 14px;
  min-width: 90px;
}
.wf-done-stat .wf-done-val {
  font-size: 1.4rem;
  font-weight: 800;
  color: var(--xword-primary);
}
.wf-done-stat .wf-done-lbl {
  font-size: 0.72rem;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.wf-done-comeback {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--xword-bg-tint);
  border: 1px dashed var(--xword-border);
  border-radius: 8px;
  padding: 10px 14px;
  margin: 4px 0 10px;
  font-size: 0.88rem;
  color: var(--xword-text);
}
.wf-done-comeback-icon { font-size: 1.05rem; line-height: 1; }
.wf-done-comeback-text { font-weight: 600; }
.wf-done-crosslink {
  display: inline-block;
  margin: 2px 0 6px;
  min-height: 44px;
  line-height: 44px;
  padding: 0 16px;
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--xword-primary);
  text-decoration: none;
  border-bottom: 2px solid var(--xword-accent);
}
.wf-done-crosslink:hover,
.wf-done-crosslink:focus {
  background: var(--xword-bg-tint);
  outline: 2px solid var(--xword-accent);
  outline-offset: 2px;
}
.wf-done-actions {
  display: flex;
  gap: 8px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 10px;
}
.wf-done-actions button {
  background: var(--xword-primary);
  color: #fff;
  border: none;
  min-height: 44px;
  padding: 8px 18px;
  border-radius: 9999px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}
.wf-done-actions button:hover,
.wf-done-actions button:focus {
  outline: 2px solid var(--xword-accent);
  outline-offset: 2px;
}
.wf-done-actions button.wf-secondary {
  background: #fff;
  color: var(--xword-primary);
  border: 1.5px solid var(--xword-primary);
}

/* Toast (hint feedback / link copied) */
.wf-toast {
  position: fixed;
  top: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(-20px);
  background: var(--xword-primary);
  color: #fff;
  padding: 10px 18px;
  border-radius: 9999px;
  font-weight: 700;
  z-index: 9100;
  opacity: 0;
  transition: opacity 0.25s, transform 0.25s;
  pointer-events: none;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}
.wf-toast.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* Score-change pulse */
.wf-score-pulse .wf-stat-score {
  animation: wf-pulse 0.45s ease-out;
}
@keyframes wf-pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.12); }
  100% { transform: scale(1); }
}

/* Print — paper-solve sheet. Unlike the crossword (blank grid), a word
   search NEEDS its letters on paper; hide solve-state highlights instead. */
@media print {
  .wf-topbar .wf-back,
  .wf-toolbar,
  .wf-done-overlay,
  .wf-toast,
  .wf-statbar,
  .wf-found-card,
  #game-help-trigger,
  #game-help-root,
  #earn-points-trigger,
  #req-popup-trigger { display: none !important; }

  @page { margin: 0.5in; }
  body.wf-page { background: #fff; color: #000; }
  body.wf-page * { color: #000 !important; box-shadow: none !important; }

  .wf-layout {
    display: block !important;
    grid-template-columns: none !important;
  }
  .wf-board-wrap {
    overflow: visible !important;
    border-color: #000 !important;
    page-break-inside: avoid;
    break-inside: avoid;
    margin-bottom: 16px;
  }

  /* Predictable grid size — 4.9in fits 14×14 at ~9mm/cell on US Letter
     with 0.5in margins. */
  table.wf-grid {
    width: 4.9in !important;
    max-width: 4.9in !important;
    margin: 0 auto;
    table-layout: fixed;
  }
  table.wf-grid td {
    border-color: #000 !important;
    background: #fff !important;
    width: auto !important;
    height: auto !important;
    font-size: 11pt;
  }

  /* Strip solve-state highlights so the printout is a fresh puzzle */
  table.wf-grid td.wf-found,
  table.wf-grid td.wf-revealed,
  table.wf-grid td.wf-sel,
  table.wf-grid td.wf-flash {
    background: #fff !important;
    outline: none !important;
    animation: none !important;
    font-weight: 600 !important;
  }

  .wf-wordlist-section {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .wf-wordlist-section ul {
    display: block !important;
    column-count: 3;
    column-gap: 24px;
  }
  .wf-word { break-inside: avoid; font-size: 10pt; }
  .wf-word .wf-word-def { display: none !important; } /* fresh-puzzle sheet */
  .wf-word.found .wf-word-term {
    text-decoration: none !important;
  }
}

/* GC Prep brand watermark (Matthew 2026-06-10): small fixed corner tag so
 * screenshots and printouts of the board carry attribution. Fixed to the
 * viewport corner — outside the grid and every interactive control — with
 * pointer-events:none so it can never intercept input or break the widget.
 * In print it repeats bottom-right of each page (position:fixed), which is
 * intentional branding; the print color-force rule turns it black and the
 * low opacity keeps it unobtrusive either way. */
body.wf-page::after {
  content: "GC PREP · gcprep.app";
  position: fixed;
  right: 10px;
  bottom: 8px;
  font: 700 10px/1 system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  letter-spacing: 0.14em;
  color: var(--xword-primary);
  opacity: 0.35;
  pointer-events: none;
  z-index: 8000; /* below overlays (9000+) so it never covers dialogs */
}

/* WCAG 2.1 §2.3.3 — Animation from Interactions. Mirror of the
   crossword.css reduced-motion block. The wf-flash-pulse + wf-pulse
   animations are suppressed when prefers-reduced-motion: reduce is
   set; gameplay (drag-to-select, word reveal) remains fully functional.
   Authored 2026-06-16 alongside the games WCAG sweep. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
