/* Word Burst — ASD-Friendly Literacy Game
 *
 * Design principles:
 *   - No pure black (#000) or pure white (#fff). Muted tones throughout.
 *   - Rounded geometry everywhere to reduce visual sharpness.
 *   - Predictable, gentle animations. No sudden movement.
 *   - Generous spacing to reduce visual crowding.
 *   - High enough contrast for readability, low enough to avoid overstimulation.
 */

:root {
  --bg: #f0ece4;
  --bg-warm: #e8e2d8;
  --card-bg: #faf8f4;
  --text: #3d3832;
  --text-muted: #7a7268;
  --primary: #6b8f71;
  --primary-hover: #5a7d60;
  --accent: #8b7355;
  --accent-light: #c4b59a;
  --success: #6b8f71;
  --success-glow: rgba(107, 143, 113, 0.35);
  --incorrect: #b07d62;
  --incorrect-glow: rgba(176, 125, 98, 0.35);
  --border: #d4cec4;
  --box-stroke: #9e9688;
  --box-fill: #faf8f4;
  --letter-bg: #e8e2d8;
  --letter-text: #3d3832;
  --letter-shadow: rgba(0, 0, 0, 0.08);
  --radius: 14px;
  --radius-sm: 10px;
  --shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  --shadow-hover: 0 4px 16px rgba(0, 0, 0, 0.1);
  --transition-smooth: 0.3s ease;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: "Nunito", "Segoe UI", system-ui, -apple-system, sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  font-size: 1rem;
  -webkit-font-smoothing: antialiased;
}

/* ── Layout ── */

.container {
  max-width: 900px;
  margin: 0 auto;
  padding: 0 1.25rem;
}

main.container {
  padding-top: 2rem;
  padding-bottom: 3rem;
}

/* ── Header ── */

.site-header {
  background: var(--primary);
  padding: 0.75rem 0;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
}

.site-header .container {
  display: flex;
  align-items: center;
}

.logo {
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--card-bg);
  text-decoration: none;
  letter-spacing: -0.02em;
}

/* ── Footer ── */

.site-footer {
  text-align: center;
  padding: 1.5rem 1.25rem;
  color: var(--text-muted);
  font-size: 0.85rem;
}

/* The policy links: muted text that warms to the primary green on hover, the
   middots between them kept a step lighter so the words carry the line. */
.legal-links .link-sep {
  color: var(--box-stroke);
}

.legal-links a {
  color: var(--text-muted);
  font-weight: 600;
  text-decoration: none;
  padding: 0 0.35rem;
  border-radius: 6px;
  transition: color var(--transition-smooth);
}

.legal-links a:hover,
.legal-links a:focus-visible {
  color: var(--primary);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── Policy pages ── */

/* The policy text sits on a card, like the completion screen. */
.policy-main {
  /* The header's .container less its padding, so the card's edge lines up
     with the logo at every width. */
  width: calc(100% - 2.5rem);
  max-width: calc(900px - 2.5rem);
  margin: 2rem auto 0;
  background: var(--card-bg);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

/* The article pads the card. Long URLs and emails may break anywhere, or a
   390px screen would scroll sideways. */
.policy-content {
  padding: 2rem;
  line-height: 1.65;
  overflow-wrap: anywhere;
}

.policy-content > :last-child {
  margin-bottom: 0;
}

.policy-content h1 {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--primary);
  margin-bottom: 0.25rem;
}

.policy-content h1 + p {
  color: var(--text-muted);
  font-size: 0.95rem;
  margin-bottom: 1.5rem;
}

.policy-content h2 {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--text);
  margin: 1.75rem 0 0.4rem;
}

.policy-content p {
  margin-bottom: 0.9rem;
}

.policy-content a {
  color: var(--primary);
  text-underline-offset: 3px;
}

.policy-content a:hover {
  color: var(--primary-hover);
}

.policy-content hr {
  border: none;
  border-top: 2px solid var(--border);
  margin: 2rem 0 1rem;
}

.policy-content hr + p {
  color: var(--text-muted);
  font-size: 0.85rem;
}

/* ── Home Page ── */

.home-container {
  max-width: 680px;
  margin: 0 auto;
}

/* Home in the Android app, which alone hands the game a privacy link: a
   screen-high column whose last item, the link, is pushed to the bottom. When
   the content is taller (the keyboard is open) the link just follows it, so
   it never covers the form. The web hosts never get this class. */
.home-app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  padding-bottom: 1.25rem;
}

/* A flex item with auto side margins shrinks to its content; keep the form's
   400px column. The bottom margin keeps a gap above the link once the free
   height runs out. */
.home-app .word-form {
  width: 100%;
  margin-bottom: 1.5rem;
}

.hero {
  text-align: center;
  margin-bottom: 2.5rem;
}

.hero h1 {
  font-size: 2rem;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 0.5rem;
}

.hero-subtitle {
  font-size: 1.1rem;
  color: var(--text-muted);
}

/* ── Word Form ── */

.word-form {
  max-width: 400px;
  margin: 0 auto;
}

.word-form-label {
  display: block;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.5rem;
}

.word-form-textarea {
  display: block;
  width: 100%;
  padding: 0.85rem 1rem;
  font-family: inherit;
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--text);
  background: var(--card-bg);
  border: 2px solid var(--border);
  border-radius: var(--radius-sm);
  resize: vertical;
  transition: border-color var(--transition-smooth);
}

.word-form-textarea:focus {
  outline: none;
  border-color: var(--primary);
}

.word-form-textarea::placeholder {
  color: var(--text-muted);
}

/* Quiet, non-blocking note about entries that will not reach the board. Warm
   brown rather than an alarm red: nobody is in trouble for typing a long word. */
.word-form-errors {
  list-style: none;
  margin-top: 0.6rem;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--incorrect);
}

.word-form-errors.hidden {
  display: none;
}

.btn-start {
  display: block;
  width: 100%;
  margin-top: 1rem;
  padding: 0.8rem;
  background: var(--primary);
  color: var(--card-bg);
  font-size: 1.1rem;
  font-weight: 700;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--transition-smooth),
              transform var(--transition-smooth);
}

.btn-start:hover {
  background: var(--primary-hover);
  transform: translateY(-1px);
}

/* Secondary action: same shape as Start, quieter colours so the two buttons
   read as a choice rather than a pair of equal shouts. The privacy link wears
   the same quiet style. */
.btn-random,
.btn-privacy {
  display: block;
  width: 100%;
  margin-top: 0.6rem;
  padding: 0.8rem;
  background: var(--card-bg);
  color: var(--primary);
  font-size: 1rem;
  font-weight: 600;
  border: 2px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color var(--transition-smooth),
              transform var(--transition-smooth);
}

.btn-random:hover,
.btn-privacy:hover {
  border-color: var(--primary);
  transform: translateY(-1px);
}

/* The last item of .home-app: the auto margin takes the free height above it.
   A link inherits the body's line-height where a button does not; normal keeps
   it the height of the buttons above. */
.btn-privacy {
  line-height: normal;
  margin-top: auto;
  align-self: center;
  max-width: 400px;
  text-align: center;
}

/* ── Loading state (shown while WASM initializes) ── */

.loading-text {
  text-align: center;
  padding: 4rem 0;
  color: var(--text-muted);
  font-size: 1.1rem;
}

/* ── Game Page ── */

.game-container {
  overscroll-behavior-x: contain;
  max-width: 800px;
  margin: 0 auto;
  padding: 0 8px;
  position: relative;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.word-controls {
  text-align: center;
  margin-top: 1rem;
  color: var(--text-muted);
}

.btn-ready,
.btn-hint {
  min-height: 48px;
  margin-top: 0.75rem;
  padding: 0.65rem 1.5rem;
  border: 2px solid var(--primary);
  border-radius: var(--radius-sm);
  background: var(--card-bg);
  color: var(--text);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.btn-ready {
  background: var(--primary);
  color: var(--card-bg);
}

.word-hint {
  min-height: 2.5rem;
  margin-top: 0.5rem;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--text);
}

/* Progress */

.game-progress {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.progress-bar {
  flex: 1;
  height: 8px;
  background: var(--border);
  border-radius: 4px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: var(--primary);
  border-radius: 4px;
  width: 0%;
  transition: width 0.5s ease;
}

.progress-text {
  font-size: 0.85rem;
  color: var(--text-muted);
  white-space: nowrap;
  min-width: 4em;
  text-align: right;
}

/* Game area */

.game-area {
  position: relative;
  width: 100%;
  aspect-ratio: 800 / 420;
  background: var(--bg-warm);
  border-radius: var(--radius);
  border: 2px solid var(--border);
  overflow: visible;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

/* SVG letter boxes (targets) */

.letter-box {
  fill: var(--box-fill);
  stroke: var(--box-stroke);
  stroke-width: 2;
  /* Corner radius is set via the rx/ry presentation attributes in View.hs;
     Firefox ignores rx/ry as CSS properties. */
}

.letter-box.filled {
  stroke: var(--primary);
  stroke-width: 2.5;
  fill: rgba(107, 143, 113, 0.08);
}

/* Quiet, steady highlights for the selected letter and empty destinations. */
.letter-box.available {
  stroke: var(--primary);
  stroke-width: 3;
  fill: rgba(107, 143, 113, 0.06);
  cursor: pointer;
}

.letter-tile.selected .letter-tile-bg {
  fill: var(--card-bg);
  stroke: var(--primary);
  stroke-width: 3;
  filter: drop-shadow(0 2px 5px var(--success-glow));
}

.box-label {
  fill: var(--text-muted);
  font-family: "Nunito", "Segoe UI", system-ui, sans-serif;
  font-size: 42px;
  font-weight: 700;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
  opacity: 0.25;
}

.box-label.filled {
  opacity: 0;
}

/* Draggable letters */

.letter-tile {
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.letter-tile:active {
  cursor: grabbing;
}

.letter-tile-bg {
  fill: var(--letter-bg);
  stroke: var(--accent-light);
  stroke-width: 2;
  /* Corner radius is set via the rx/ry presentation attributes in View.hs;
     Firefox ignores rx/ry as CSS properties. */
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.08));
  transition: fill 0.2s ease, stroke 0.2s ease;
}

.letter-tile.dragging {
  transition: none;
}

.letter-tile.dragging .letter-tile-bg {
  fill: var(--card-bg);
  stroke: var(--primary);
  stroke-width: 2.5;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.15));
}

/* Scale wrapper — animates the tile to 2× on pickup and back on release.
 *
 * The inner <g>'s children are centred at (0,0) and the outer <g> translates
 * to the tile centre, so a plain CSS scale() from the default origin expands
 * symmetrically. The scale value is set via inline style from Haskell;
 * this class just provides the transition.
 */
.letter-tile-scale {
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.letter-tile-text {
  fill: var(--letter-text);
  font-family: "Nunito", "Segoe UI", system-ui, sans-serif;
  font-size: 42px;
  font-weight: 700;
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

/* Explosion animation: letters transition from box positions to scattered positions */

.letter-tile {
  transition: transform 1.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.letter-tile.snapping {
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.letter-tile.snapped {
  opacity: 0.6;
}

.letter-tile.snapped .letter-tile-bg {
  fill: rgba(107, 143, 113, 0.12);
  stroke: var(--primary);
}

/* Feedback overlay */

.feedback {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  border-radius: var(--radius);
  z-index: 100;
  gap: 1rem;
}

.feedback.hidden {
  display: none;
}

.feedback-icon {
  font-size: 3rem;
  line-height: 1;
}

.feedback-text {
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--text);
}

.feedback.correct .feedback-icon { color: var(--success); }
.feedback.incorrect .feedback-icon { color: var(--incorrect); }

/* Completion screen */

.complete {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 320px;
  padding: 3rem 1.5rem;
  background: var(--card-bg);
  border-radius: var(--radius);
  border: 2px solid var(--border);
}

.complete-content {
  text-align: center;
  max-width: 400px;
}

.complete-content h2 {
  font-size: 2rem;
  font-weight: 700;
  color: var(--primary);
  margin-bottom: 0.75rem;
}

.complete-content p {
  font-size: 1.15rem;
  line-height: 1.6;
  color: var(--text-muted);
  margin-bottom: 2rem;
}

/* Buttons */

.btn {
  display: inline-block;
  padding: 0.7rem 1.5rem;
  border: none;
  border-radius: var(--radius-sm);
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition-smooth),
              transform var(--transition-smooth),
              box-shadow var(--transition-smooth);
}

.btn-next {
  background: var(--primary);
  color: var(--card-bg);
}

.btn-next:hover {
  background: var(--primary-hover);
  transform: translateY(-1px);
  box-shadow: var(--shadow-hover);
}

.btn-home {
  background: var(--primary);
  color: var(--card-bg);
}

.btn-home:hover {
  background: var(--primary-hover);
  transform: translateY(-1px);
  box-shadow: var(--shadow-hover);
}

/* ── Responsive ── */

@media (max-width: 600px) {
  .hero h1 {
    font-size: 1.6rem;
  }

  .phase-grid {
    grid-template-columns: 1fr;
  }
}
