/* Puzzle Parlor — styles
   Design goals: large type, large tap targets, high contrast, no surprises. */

:root {
  --bg: #fdf8f0;
  --bg-tint: #f7eddd;
  --panel: #ffffff;
  --ink: #251d38;
  --ink-soft: #5c5472;
  --line: #e4d8c5;
  --line-strong: #cbb99f;
  --brand: #6d28d9;
  --brand-dark: #53199f;
  --brand-soft: #ede9fe;
  --teal: #0f766e;
  --accent: #b45309;
  --good: #15803d;
  --shadow-1: 0 2px 4px rgba(37, 29, 56, .08), 0 8px 20px rgba(37, 29, 56, .10);
  --shadow-2: 0 6px 14px rgba(37, 29, 56, .14), 0 18px 40px rgba(37, 29, 56, .16);
  --radius: 16px;
  --radius-lg: 24px;
  --gap: 12px;
  --base: 18px;
  --focus: 0 0 0 4px #ffffff, 0 0 0 8px var(--brand);
}

html { font-size: var(--base); }
html[data-text="large"] { --base: 21px; }
html[data-text="xlarge"] { --base: 24px; }

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--bg);
  background-image: radial-gradient(circle at 12% 0%, #fff6e6 0%, transparent 55%),
                    radial-gradient(circle at 100% 100%, #f0f7f4 0%, transparent 50%);
  color: var(--ink);
  font-family: "Avenir Next", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  font-size: 1rem;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  /* a game should never rubber-band or pull-to-refresh under the thumb */
  overscroll-behavior: none;
}

/* the playing surface: no text selection, no long-press menu, no double-tap zoom */
.stage,
.toolbar,
.hud {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.stage { touch-action: none; }

h1, h2 { line-height: 1.2; margin: 0; }

:focus-visible { outline: none; box-shadow: var(--focus); border-radius: 8px; }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--panel);
  color: var(--ink);
  padding: .6rem 1rem;
  z-index: 100;
  border-radius: 0 0 var(--radius) 0;
  font-weight: 600;
}
.skip-link:focus { left: 0; }

.app {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  height: 100dvh;
  padding: max(8px, env(safe-area-inset-top)) clamp(10px, 2.2vw, 24px) max(6px, env(safe-area-inset-bottom));
  gap: 8px;
}

/* ---------------- top bar ---------------- */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--gap);
  flex: 0 0 auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: .55rem;
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -.01em;
  color: var(--ink);
}

.brand-mark {
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 8px;
  background:
    radial-gradient(circle at 30% 30%, #fbbf24 0 42%, transparent 43%),
    radial-gradient(circle at 72% 72%, #34d399 0 42%, transparent 43%),
    var(--brand);
  box-shadow: var(--shadow-1);
  flex: 0 0 auto;
}

.topbar-tools { display: flex; gap: 8px; flex-wrap: wrap; }

/* ---------------- buttons ---------------- */

.btn {
  font: inherit;
  font-size: .95rem;
  font-weight: 650;
  color: var(--ink);
  background: var(--panel);
  border: 2px solid var(--line);
  border-radius: 999px;
  min-height: 52px;
  padding: .55rem 1.1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  cursor: pointer;
  box-shadow: var(--shadow-1);
  transition: transform .08s ease, background .15s ease, border-color .15s ease;
  touch-action: manipulation;
}
.btn:hover { background: #fbf6ee; border-color: var(--line-strong); }
.btn:active { transform: translateY(1px) scale(.99); }

.btn[aria-pressed="true"] {
  background: var(--brand-soft);
  border-color: var(--brand);
  color: var(--brand-dark);
}

.btn-primary {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}
.btn-primary:hover { background: var(--brand-dark); border-color: var(--brand-dark); }

.btn-wide { width: 100%; max-width: 32rem; font-size: 1.05rem; min-height: 60px; }

.btn .ico { font-size: 1.1em; line-height: 1; }
.btn .lbl { white-space: nowrap; }

/* Buttons carry a long and a short label; narrow screens use the short one so
   the toolbar stays two rows instead of seven on a 320px screen. */
.lbl-short { display: none; }

/* ---------------- fields ---------------- */

.field { display: inline-flex; flex-direction: column; gap: 2px; }

.field-label {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-left: .3rem;
}

select {
  font: inherit;
  font-size: .95rem;
  font-weight: 600;
  color: var(--ink);
  background: var(--panel);
  border: 2px solid var(--line);
  border-radius: 999px;
  min-height: 52px;
  padding: .5rem 2.2rem .5rem 1.1rem;
  cursor: pointer;
  box-shadow: var(--shadow-1);
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%235c5472' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
}
select:hover { border-color: var(--line-strong); background-color: #fbf6ee; }

/* ---------------- screens ---------------- */

main { flex: 1 1 auto; min-height: 0; display: flex; }

.screen {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.screen[hidden] { display: none; }

/* home */

.screen-home {
  align-items: center;
  justify-content: flex-start;
  overflow-y: auto;
  padding-bottom: 1rem;
}

.welcome {
  margin: .25rem 0 0;
  font-size: 1.05rem;
  color: var(--ink-soft);
  text-align: center;
  max-width: 34rem;
}

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: clamp(12px, 2.5vw, 28px);
  width: 100%;
  max-width: 76rem;
  margin-top: .4rem;
}

.card {
  font: inherit;
  color: var(--ink);
  text-align: left;
  background: var(--panel);
  border: 3px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(14px, 2vw, 22px);
  display: flex;
  flex-direction: column;
  gap: .4rem;
  cursor: pointer;
  box-shadow: var(--shadow-1);
  transition: transform .1s ease, box-shadow .18s ease, border-color .18s ease;
  min-height: 210px;
}
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); border-color: var(--brand); }
.card:active { transform: translateY(0) scale(.995); }

.card-art { display: block; margin-bottom: .35rem; }
.card-art svg { width: clamp(90px, 13vw, 140px); height: auto; display: block; }

.card-title { font-size: 1.5rem; font-weight: 800; letter-spacing: -.01em; }
.card-sub { font-size: .98rem; color: var(--ink-soft); }

.resume-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 100%;
  max-width: 34rem;
  margin-top: .5rem;
  padding: 14px;
  background: var(--brand-soft);
  border: 2px dashed var(--brand);
  border-radius: var(--radius);
}

.help {
  width: 100%;
  max-width: 46rem;
  margin-top: .6rem;
  background: var(--panel);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  padding: .3rem .4rem;
}
.help summary {
  cursor: pointer;
  font-weight: 700;
  padding: .8rem .7rem;
  border-radius: 12px;
  font-size: 1.02rem;
}
.help summary:hover { background: var(--bg-tint); }
.help-body { padding: .2rem 1.4rem 1rem; color: var(--ink-soft); }
.help-body h2 { font-size: 1.05rem; color: var(--ink); margin-top: 1rem; }
.help-body ul { margin: .4rem 0 0; padding-left: 1.3rem; }
.help-body li { margin: .3rem 0; }

/* games */

.screen-game { gap: 6px; }

.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px;
  flex: 0 0 auto;
}

.statusline {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  flex: 0 0 auto;
  font-size: .98rem;
  color: var(--ink-soft);
  flex-wrap: nowrap;
  min-width: 0;
}
/* the wording gives way before the progress bar does on a narrow screen */
.statusline > span:not(.progress) {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.statusline strong { color: var(--ink); font-size: 1.1rem; }
.statusline-split { justify-content: space-between; }
.statusline-split > span { white-space: nowrap; }

.progress {
  flex: 1 1 8rem;
  min-width: 6rem;
  height: 14px;
  background: #eadfcc;
  border-radius: 999px;
  overflow: hidden;
  display: block;
}
.progress-fill {
  display: block;
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--teal), #22c55e);
  border-radius: 999px;
  transition: width .35s ease;
}

.stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  border-radius: var(--radius);
  background: var(--panel);
  border: 2px solid var(--line);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}

.stage canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
  cursor: pointer;
}
.stage canvas.grabbing { cursor: grabbing; }

.stage-msg {
  position: absolute;
  inset: auto 0 0 0;
  top: 50%;
  transform: translateY(-50%);
  margin: auto;
  height: fit-content;
  width: fit-content;
  max-width: 90%;
  text-align: center;
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--ink);
  background: rgba(255, 255, 255, .95);
  border: 3px solid var(--brand);
  border-radius: var(--radius-lg);
  padding: 1rem 1.5rem;
  box-shadow: var(--shadow-2);
  pointer-events: none;
}
.stage-msg small { display: block; font-size: .8rem; font-weight: 600; color: var(--ink-soft); margin-top: .35rem; }

.footnote {
  flex: 0 0 auto;
  margin: 0;
  text-align: center;
  font-size: .8rem;
  color: var(--ink-soft);
}

/* ---------------- choose a puzzle ---------------- */

.screen-choose {
  overflow-y: auto;
  padding-bottom: 1rem;
  gap: 12px;
}

.choose-head { display: flex; flex-direction: column; gap: 2px; }
.choose-heading { font-size: 1.4rem; font-weight: 800; }
.choose-current { margin: 0; color: var(--ink-soft); font-size: .98rem; }

.choose-label {
  margin: 0 0 6px;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-left: .3rem;
}

.piece-row { display: flex; flex-wrap: wrap; gap: 8px; }

.piece-choice {
  flex-direction: column;
  gap: 0;
  min-width: 5.4rem;
  padding: .35rem .9rem;
  line-height: 1.15;
}
.piece-choice strong { font-size: 1.15rem; font-weight: 800; }
.piece-choice span { font-size: .74rem; font-weight: 600; color: var(--ink-soft); }
.piece-choice[aria-pressed="true"] span { color: var(--brand-dark); }

.picture-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: clamp(10px, 1.6vw, 18px);
  margin-top: 2px;
}

.picture-card {
  font: inherit;
  color: var(--ink);
  background: var(--panel);
  border: 3px solid var(--line);
  border-radius: var(--radius);
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  cursor: pointer;
  box-shadow: var(--shadow-1);
  transition: transform .1s ease, border-color .16s ease, box-shadow .16s ease;
  text-align: left;
}
.picture-card:hover { transform: translateY(-3px); border-color: var(--brand); box-shadow: var(--shadow-2); }
.picture-card:active { transform: translateY(0) scale(.995); }

.picture-card canvas,
.picture-thumb {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  background: var(--bg-tint);
  object-fit: cover;
}
.photo-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.6rem;
  background: linear-gradient(140deg, var(--brand-soft), #dbeafe);
}

.picture-name { font-size: 1rem; font-weight: 700; margin-top: 6px; }
.picture-note { font-size: .78rem; color: var(--ink-soft); }
.picture-card.is-current { border-color: var(--brand); background: var(--brand-soft); }
.picture-card.is-current .picture-name::after {
  content: " · playing";
  font-size: .78rem;
  font-weight: 700;
  color: var(--brand-dark);
}

/* ---------------- game HUD ---------------- */

.hud {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  flex-wrap: wrap;
  min-height: 0;
}

.pill {
  display: inline-flex;
  align-items: baseline;
  gap: .4rem;
  background: var(--panel);
  border: 2px solid var(--line);
  border-radius: 999px;
  padding: .3rem .85rem;
  box-shadow: var(--shadow-1);
  white-space: nowrap;
}
.pill-k {
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.pill strong { font-size: 1.15rem; font-weight: 800; color: var(--ink); }
.pill-best strong { color: var(--accent); }
.pill-level strong { color: var(--teal); }

/* score ticks up rather than jumping */
.pill strong.bump { animation: bump .28s ease-out; }
@keyframes bump {
  0% { transform: scale(1); }
  45% { transform: scale(1.28); }
  100% { transform: scale(1); }
}

.hud-help {
  margin: 0 0 0 auto;
  font-size: .85rem;
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* visible to screen readers only */
.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------------- the frog's arrow buttons ---------------- */

.dpad {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  flex: 0 0 auto;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

.dpad-btn {
  font: inherit;
  font-size: 1.5rem;
  line-height: 1;
  font-weight: 800;
  color: #14532d;
  background: linear-gradient(#f0fdf4, #dcfce7);
  border: 2px solid #86efac;
  border-radius: 16px;
  min-height: 62px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: var(--shadow-1);
  touch-action: manipulation;
  transition: transform .07s ease, background .12s ease;
}
.dpad-btn:hover { background: #dcfce7; }
.dpad-btn:active,
.dpad-btn.is-down { transform: translateY(2px) scale(.97); background: #bbf7d0; }
/* forward is the move that matters most, so it gets the emphasis */
.dpad-up {
  background: linear-gradient(#22c55e, #16a34a);
  border-color: #15803d;
  color: #ffffff;
  font-size: 1.7rem;
}
.dpad-up:hover { background: linear-gradient(#16a34a, #15803d); }
.dpad-up:active,
.dpad-up.is-down { background: #15803d; }

.pill-lives strong { color: #dc2626; letter-spacing: .06em; }

/* ---------------- toast ---------------- */

.toast {
  position: fixed;
  left: 50%;
  bottom: max(18px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  background: var(--ink);
  color: #fff;
  font-weight: 650;
  padding: .7rem 1.2rem;
  border-radius: 999px;
  box-shadow: var(--shadow-2);
  z-index: 60;
  max-width: 90vw;
  text-align: center;
}
.toast[hidden] { display: none; }

/* ---------------- confetti ---------------- */

.confetti { position: fixed; inset: 0; pointer-events: none; z-index: 70; overflow: hidden; }
.confetti[hidden] { display: none; }
.confetti i {
  position: absolute;
  top: -24px;
  width: 12px;
  height: 18px;
  border-radius: 3px;
  animation: fall linear forwards;
}
@keyframes fall {
  0% { transform: translateY(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(105vh) rotate(720deg); opacity: .9; }
}

/* ---------------- small screens ---------------- */

/* Comfort settings keep their labels but drop the current value, and the game
   chrome gets shorter, so a phone spends its height on the game rather than on
   buttons. */
@media (max-width: 760px) {
  .cards { grid-template-columns: 1fr; max-width: 30rem; }
  .card { min-height: 0; }
  .card-art svg { width: 84px; }
  .brand { font-size: 1.1rem; }
  .brand-mark { width: 1.3rem; height: 1.3rem; }
  .btn .lbl { font-size: .9rem; }
  .topbar .val { display: none; }
  .topbar { gap: 6px; }
  .topbar-tools { gap: 6px; }
  .topbar .btn, .toolbar .btn, .toolbar select { min-height: 48px; }
  .topbar .btn { padding: .4rem .75rem; }
  .toolbar .btn { padding: .4rem .8rem; }
  .toolbar { gap: 6px; }
  .footnote { display: none; }
  .hud-help { display: none; }
  .app { gap: 8px; }
  .pill { padding: .22rem .7rem; }
  .pill strong { font-size: 1.05rem; }
  /* a label beside its menu instead of above it keeps the toolbar one row */
  .toolbar .field { flex-direction: row; align-items: center; gap: .45rem; }
  .toolbar .field-label { padding-left: 0; }
}

@media (max-width: 560px) {
  /* The puzzle menu already offers the picture and the piece count as big
     cards and buttons, so the two duplicate menus step off the toolbar and the
     board gets the height instead. */
  #pz-picture-field,
  #pz-pieces-field { display: none; }

  .lbl-long { display: none; }
  .lbl-short { display: inline; }

  /* The three comfort buttons keep their words and the app name steps aside —
     a tappable label is worth more than a title the player already knows. The
     name stays in the accessibility tree for screen readers. */
  .brand-name {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .brand { gap: 0; }
  .topbar .btn { padding: .35rem .6rem; font-size: .85rem; }
  .topbar-tools { gap: 5px; }
  .topbar { gap: 6px; }
}

/* An iPhone SE / small phone is only 320pt wide: the comfort buttons become
   icons so the header still fits on one line, and the game gets the height. */
@media (max-width: 400px) {
  .topbar .lbl { display: none; }
  .topbar .btn { min-width: 44px; padding: .35rem .5rem; }
  .topbar .ico { font-size: 1.15rem; }
  .toolbar { gap: 5px; }
  .toolbar .btn { padding: .3rem .5rem; min-height: 46px; }
  .toolbar .btn .lbl { font-size: .82rem; }
  .toolbar .ico { display: none; }
  .toolbar select { padding: .3rem 1.5rem .3rem .6rem; min-height: 46px; font-size: .88rem; }
  .pill { padding: .18rem .5rem; gap: .25rem; }
  .pill strong { font-size: .98rem; }
  .pill-k { font-size: .58rem; }
  .hud { gap: 5px; }
  /* the level is painted on the board instead, which saves a whole row */
  .dpad-btn { min-height: 54px; font-size: 1.35rem; border-radius: 13px; }
  .dpad-up { font-size: 1.5rem; }
}

@media (max-width: 420px) {
  .pill-k { font-size: .62rem; }
  .pill { gap: .3rem; padding: .2rem .58rem; }
  .field-label { display: none; }
  .toolbar select { padding-top: .3rem; padding-bottom: .3rem; }
}

/* Short screens (a landscape phone): drop everything that is not the game. */
@media (max-height: 560px) {
  .topbar .lbl { display: none; }
  .topbar .btn { min-width: 48px; padding: .4rem .6rem; }
  .topbar { gap: 8px; }
  .topbar .brand { font-size: 1rem; }
  .footnote { display: none; }
  .hud-help { display: none; }
  .toolbar .field-label { display: none; }
  .app { gap: 6px; }
  .hud { gap: 6px; }
}

/* A landscape phone is short and wide, so the frog's arrow buttons move to the
   side of the board instead of below it — that is worth about a third more
   board, which is the difference between playable and not. */
@media (orientation: landscape) and (max-height: 560px) {
  .screen-crossy {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 86px;
    grid-template-rows: auto auto minmax(0, 1fr);
    gap: 6px;
  }
  .screen-crossy .toolbar { grid-column: 1 / -1; grid-row: 1; }
  .screen-crossy .hud { grid-column: 1 / -1; grid-row: 2; }
  .screen-crossy .stage { grid-column: 1; grid-row: 3; }
  .screen-crossy .dpad {
    grid-column: 2;
    grid-row: 3;
    grid-template-columns: 1fr;
    grid-template-rows: repeat(4, minmax(0, 1fr));
    gap: 6px;
  }
  .screen-crossy .dpad-btn { min-height: 0; font-size: 1.2rem; }
}

@media (max-height: 640px) {
  .screen-home { justify-content: flex-start; }
}

/* respect users who do not want motion */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
  .card:hover { transform: none; }
}
html[data-motion="calm"] .confetti { display: none !important; }
html[data-motion="calm"] .card:hover { transform: none; }

/* ---------------- language switch & a roomier board ---------------- */

/* The label sits beside its menu, not above it, so the toolbar stays one row
   and the board gets the height. */
.toolbar .field { flex-direction: row; align-items: center; gap: .45rem; }
.toolbar .field-label { padding-left: 0; }

/* The comfort buttons and the toolbar can each give up a few pixels; 48px is
   still a very comfortable target. (The small-screen rules down to 46px still
   win on the narrowest phones.) */
@media (min-width: 761px) {
  .topbar .btn, .toolbar .btn, .toolbar select { min-height: 48px; }
}

/* The privacy line lives on the home and menu screens; while a game is up the
   board takes that height instead. Browsers that do not know :has simply keep
   the line — nothing breaks. */
body:has(.screen-game:not([hidden])) .footnote { display: none; }

/* The language switch shows its short badge from main-mobile width down, and
   drops the words entirely on a phone, so the header stays a single row. */
@media (max-width: 760px) {
  #btn-lang .lbl-long { display: none; }
  #btn-lang .lbl-short { display: inline; }
}
@media (max-width: 470px) {
  #btn-lang .lbl { display: none; }
}

/* the "playing" note on a picture card follows the chosen language */
html[lang="es"] .picture-card.is-current .picture-name::after { content: " · en juego"; }
