/* CasaPlay theme: same "Sapphire nightfall" roles as DecoTools (src/app/globals.css). Dark only.
   Shared by the portal and every game: <link rel="stylesheet" href="/theme.css">
   Mobile-first: see docs/mobile-design.md for the rules these classes follow. */
@import url("/vendor/jetbrains-mono/index.css");

:root {
  color-scheme: dark;
  --background: #1d2133; /* page */
  --foreground: #d6e0f5; /* main text */
  --card: #272d45; /* elevated: cards, panels */
  --popover: #232840; /* menus, dialogs, sheets */
  --primary: #1a7fd6; /* solid actions, focus ring */
  --primary-foreground: #ffffff;
  --brand: #6f9be0; /* links, icons, tinted fills */
  --muted: color-mix(in oklab, var(--foreground) 8%, var(--background));
  --muted-foreground: color-mix(in oklab, var(--foreground) 62%, var(--background));
  --secondary: color-mix(in oklab, var(--foreground) 12%, var(--background));
  --accent: color-mix(in oklab, var(--brand) 22%, var(--background));
  --border: color-mix(in oklab, var(--brand) 30%, transparent);
  --control-border: color-mix(in oklab, var(--brand) 75%, var(--background));
  --field: color-mix(in oklab, var(--foreground) 8%, var(--background));
  --destructive: #e5705a;
  --green: #5fb97f;
  --yellow: #e8b04a;
  --radius: 0.5rem; /* cards and panels; buttons, icon buttons, fields and tags are pills or circles (see docs/mobile-design.md) */
  --on-color: #1d2133; /* text on the green, red and yellow fills: the white of --primary-foreground is too weak on them */
  --font: "JetBrains Mono Variable", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --gutter: 16px; /* page side padding */
  --top: max(40px, env(safe-area-inset-top)); /* space above everything: keeps content off the status bar, the camera cut-out and the browser bar */
  --tap: 48px; /* minimum touch target (44px is the floor) */
  --hud-h: 48px; /* height of the HUD strip: the same as a corner button, so both sit on one row */
  --hud-clear: 60px; /* what the corner bar takes on the right of the HUD strip: Leave (48px) and a gap; 116px with a Pause button */
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  padding: var(--top) max(var(--gutter), env(safe-area-inset-right)) max(var(--gutter), env(safe-area-inset-bottom)) max(var(--gutter), env(safe-area-inset-left));
  background: var(--background);
  color: var(--foreground);
  font: 16px/1.5 var(--font);
  overscroll-behavior-y: none; /* no pull-to-refresh or bounce while playing */
}
/* A page with a bottom action (.dock): the body is a column, so a short page pushes the dock to the bottom of the screen. */
body.has-dock { display: flex; flex-direction: column; }

a { color: var(--brand); }
a.btn { text-decoration: none; }
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
[hidden] { display: none !important; }

.page { width: 100%; max-width: 560px; margin: 0 auto; display: grid; gap: 20px; }
.msg { color: var(--muted-foreground); }
.err { color: var(--destructive); margin: 0; }
.label { margin: 0 0 8px; font-size: 12px; font-weight: 400; letter-spacing: .12em; text-transform: uppercase; color: var(--muted-foreground); }

.card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 16px; }

/* Buttons: 48px tall, fully rounded, readable, no text selection on long press.
   Color says what it does: .go (green) starts or plays, .danger (red) leaves or deletes, blue continues or sets up, .secondary does nothing by itself (Close, Back). */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tap); padding: 0 22px; border: 1px solid transparent; border-radius: 999px; white-space: nowrap;
  background: var(--primary); color: var(--primary-foreground); font: inherit; font-weight: 700; cursor: pointer;
  user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; touch-action: manipulation;
  transition: transform .08s ease, background-color .15s ease;
}
.btn.secondary { background: var(--secondary); color: var(--foreground); border-color: var(--border); }
.btn.go { background: var(--green); color: var(--on-color); }
.btn.danger { background: var(--destructive); color: var(--on-color); }
.btn.small { min-height: 44px; padding: 0 16px; }
.btn.block { width: 100%; }
.btn.big { min-height: 56px; font-size: 18px; }
.btn:active { transform: scale(.97); }
.btn:disabled { opacity: .5; cursor: default; transform: none; }

/* Text field: 16px font, or iOS zooms the page when it gets focus */
.input {
  width: 100%; min-height: var(--tap); padding: 0 20px; border-radius: 999px;
  border: 1px solid var(--control-border); background: var(--field); color: var(--foreground); font: inherit; font-size: 16px;
}
.input::placeholder { color: color-mix(in oklab, var(--foreground) 62%, var(--field)); }
.input.ok { border-color: var(--green); }

.tag { padding: 2px 10px; border-radius: 99px; background: var(--muted); border: 1px solid var(--border); color: var(--muted-foreground); font-size: 13px; }

/* Bottom action: floating pills with no bar behind them. It sits after the content (nothing is hidden under it), is pushed to the
   bottom of a short page and sticks to the bottom of a long one. */
.dock {
  position: sticky; bottom: max(var(--gutter), env(safe-area-inset-bottom)); z-index: 900; margin-top: auto; padding-top: 20px;
  pointer-events: none; /* only the buttons take taps */
}
.dock-inner { max-width: 560px; margin: 0 auto; display: flex; gap: 10px; }
.dock-inner .btn { flex: 1; pointer-events: auto; box-shadow: 0 6px 18px rgb(0 0 0 / .4); }

/* Game page header: the back button on its own row (the top-right buttons sit beside it) and the title below, so no title is cut. */
.game-head { display: grid; gap: 8px; min-height: 44px; }
.game-head a { text-decoration: none; justify-self: start; }
.game-head h1 { margin: 0; font-size: 24px; line-height: 1.2; text-wrap: balance; overflow-wrap: anywhere; }

/* Top-right buttons (QR, full screen). One container, so a hidden button never leaves a gap. */
.cp-actions { position: fixed; top: var(--top); right: max(var(--gutter), env(safe-area-inset-right), calc((100vw - 560px) / 2)); z-index: 1000; display: flex; gap: 8px; }
body.cp-immersive .cp-actions > :not(.cp-leave) { display: none; } /* during a round, so a stray tap cannot toggle them; Leave stays */
.cp-leave { order: -1; }
.cp-pause { order: -2; } /* Pause sits left of Leave */
body.cp-immersive .cp-actions > .cp-pause { display: grid; } /* and stays during a round, like Leave */
body.cp-has-pause { --hud-clear: 116px; }
body.cp-immersive.cp-has-leave .page:not(:has(.hud:not([hidden]))) { padding-top: 60px; } /* a screen with no HUD strip keeps clear of the Leave button */

/* The HUD strip: the first row of a round screen, level with the corner bar and clear of it (docs/mobile-design.md, "HUD layout").
   start: the main status (score, level, time, round); mid: optional; end: lives and resources. Nothing in it is tappable, except what a game puts in the bottom bar. */
.hud { width: 100%; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px; min-height: var(--hud-h); padding-right: var(--hud-clear); font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; }
.hud[hidden] { display: none; }
.hud-start, .hud-mid, .hud-end { display: flex; align-items: center; gap: 8px; min-width: 0; }
.hud-start { grid-column: 1; justify-self: start; }
.hud-mid { grid-column: 2; justify-self: center; }
.hud-end { grid-column: 3; justify-self: end; }
.cp-fs, .icon-btn {
  position: relative; width: 48px; height: 48px; display: grid; place-items: center; padding: 0; flex: none;
  border: 1px solid var(--border); border-radius: 50%; cursor: pointer;
  background: color-mix(in oklab, var(--popover) 85%, transparent); color: var(--foreground); backdrop-filter: blur(6px);
  touch-action: manipulation;
}
.icon-btn.go { background: var(--green); color: var(--on-color); border-color: transparent; }
.icon-btn.danger, .cp-fs.danger { background: var(--destructive); color: var(--on-color); border-color: transparent; }
.cp-fs.fullscreen { order: 2; }
.cp-fs.spin svg { animation: cp-spin .8s linear infinite; }
@keyframes cp-spin { to { transform: rotate(360deg); } }
/* Badge on an icon button: a count (blue) or "!" (yellow, .warn) */
.badge {
  position: absolute; top: -7px; right: -7px; min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 99px; border: 2px solid var(--background); background: var(--primary); color: var(--primary-foreground);
  font-size: 11px; font-weight: 700; line-height: 16px; text-align: center; pointer-events: none;
}
.badge.warn { background: var(--yellow); color: #1d2133; }
.cp-fs svg, .icon-btn svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Dialog (QR code, install hint, forms): centered on the screen on every size, inside the safe areas; a tall one scrolls inside its card */
.cp-help {
  position: fixed; inset: 0; z-index: 1001; display: flex; align-items: center; justify-content: center; background: rgb(0 0 0 / .6);
  padding: max(20px, env(safe-area-inset-top)) max(20px, env(safe-area-inset-right)) max(20px, env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left));
}
.cp-help .card {
  width: 100%; max-width: 480px; max-height: 100%; overflow: auto; background: var(--popover);
  border-radius: 16px; padding: 20px var(--gutter) 16px;
  animation: cp-pop .2s ease-out;
}
.cp-help h2 { margin: 0 0 10px; font-size: 18px; }
.cp-help p { margin: 0 0 12px; }
.cp-help .btn { width: 100%; }
/* The main action keeps 20px from the text, field or label above it; buttons stacked together stay 8px apart */
.cp-help .card > .btn { margin-top: 20px; }
.cp-help .card > .btn + .btn { margin-top: 8px; }
@keyframes cp-pop { from { transform: scale(.96); opacity: 0; } }

/* Top 10 ranking (CasaPlay.renderTop) */
.top { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.top li { display: grid; grid-template-columns: 2.2em auto 1fr auto; align-items: center; gap: 8px; min-height: 52px; padding: 8px 14px 8px 12px; border-radius: 26px; background: var(--muted); border: 1px solid transparent; }
.top li.me { background: var(--accent); border-color: var(--border); }
.top li:nth-child(-n+3) .rank { color: var(--yellow); font-weight: 700; }
.top .rank { color: var(--muted-foreground); }
.top .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.top .score { font-weight: 700; color: var(--brand); }

/* Player picture (CasaPlay.avatar): a round picture, or the first letter of the nickname when there is none */
.avatar {
  --size: 40px; flex: none; display: inline-grid; place-items: center; overflow: hidden;
  width: var(--size); height: var(--size); border-radius: 50%; border: 2px solid var(--border);
  background: var(--accent); color: var(--brand); font-size: calc(var(--size) * .45); font-weight: 700; line-height: 1;
}
.avatar img { display: block; width: 100%; height: 100%; object-fit: cover; }
.player { display: flex; align-items: center; gap: 12px; min-width: 0; } /* CasaPlay.playerChip */
.player .pname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; }

/* Choice pill (filters): pressed shows a check mark, so the state is not only a color */
.chip-btn {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 18px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--secondary); color: var(--foreground); font: inherit; cursor: pointer;
  touch-action: manipulation; user-select: none; -webkit-user-select: none;
}
.chip-btn[aria-pressed="true"] { background: var(--accent); border-color: var(--brand); font-weight: 700; }
.chip-btn[aria-pressed="true"]::before { content: "\2713"; color: var(--green); }

/* Game rules (the "?" button opens them) */
.rules { margin: 0 0 12px; padding-left: 1.8em; display: grid; gap: 10px; line-height: 1.45; }
.rules li::marker { color: var(--brand); font-weight: 700; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* Tabs on the start screen of a game (/game-tabs.js): Play (options, how to play, sound) and Score (profile, Top 10). */
.cp-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px; margin-bottom: 16px; border-radius: 999px; background: var(--field); border: 1px solid var(--control-border); }
.cp-cover { display: block; width: 96px; height: 96px; margin: 0 auto 16px; border-radius: 22px; object-fit: cover; }
.cp-cover[hidden] { display: none; }
.cp-tabs[hidden], .cp-off { display: none !important; }
.cp-tabs button { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 8px; border: 1px solid transparent; border-radius: 999px; background: none; color: var(--muted-foreground); font: inherit; cursor: pointer; touch-action: manipulation; }
.cp-tabs button[aria-selected="true"] { background: var(--accent); border-color: var(--brand); color: var(--foreground); font-weight: 700; }
.cp-tabs svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* The animation card at the top of every game's Play tab: it shows how to play, with no words (the rules are behind the ? button). */
.hero { position: relative; overflow: hidden; height: 138px; padding: 0; background: radial-gradient(120% 140% at 80% 50%, color-mix(in oklab, var(--primary) 30%, var(--card)), var(--card)); }
.hero > svg { display: block; width: 100%; height: 100%; }
