/* Product tokens (1p ui/src/index.css), as in the dashboard redesign */
:root{
  --background:60 25% 98%; --foreground:60 3% 6%; --card:0 0% 100%;
  --muted:50 12% 91%; --muted-foreground:45 2% 38%; --border:50 14% 92%; --input:50 10% 89%;
  /* A fill inside a card (the dashboard's --well): muted in light; in dark muted is as light as the card, so the page colour. */
  --well:50 12% 91%;
  --tone-success:162.9 93.5% 24.3%; --tone-danger:0 73.7% 41.8%; --tone-info:224.3 76.3% 48%;
  --status-done:160 84% 39%; --status-running:217 91% 60%; --destructive:0 72% 51%;
  --wash-cool:230 31% 48%; --wash-cool-a:.10; --wash-warm:19 52% 57%; --wash-warm-a:.08;
  --shadow-surface:0 1px 6px rgb(0 0 0/.04),0 0 24px rgb(0 0 0/.05);
  --shadow-raised:0 2px 8px rgb(0 0 0/.06),0 0 32px rgb(0 0 0/.08);
  --shadow-floating:0 3px 16px rgb(0 0 0/.1),0 0 40px rgb(0 0 0/.08);
  --primary:40 4% 14%; --primary-foreground:60 25% 98%;
  --red-1:#f2301b; --red-2:#ff6a4d; --red-3:#c4210f;
  color-scheme:light;
}
@media (prefers-color-scheme: dark){
  :root{
    --background:60 3% 14%; --foreground:45 10% 92%; --card:60 1% 19%;
    --muted:30 2% 19%; --muted-foreground:48 3% 65%; --border:40 3% 17%; --input:40 3% 23%; --well:60 3% 14%;
    --tone-success:158 64% 52%; --tone-danger:0 91% 71%; --tone-info:213 94% 68%; --destructive:0 91% 71%;
    --wash-cool:233 35% 59%; --wash-warm-a:.07;
    --shadow-surface:0 0 0 1px rgb(255 255 255/.06),0 0 24px rgb(0 0 0/.35);
    --shadow-raised:0 0 0 1px rgb(255 255 255/.09),0 0 32px rgb(0 0 0/.5);
    --shadow-floating:0 0 0 1px rgb(255 255 255/.1),0 8px 32px rgb(0 0 0/.55);
    --primary:45 10% 92%; --primary-foreground:60 4% 10%;
    color-scheme:dark;
  }
}
*,*::before,*::after{ box-sizing:border-box; corner-shape:squircle }
html{ height:100% }
body{ margin:0; min-height:100%; display:flex; flex-direction:column;
  font-family:Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif; font-size:14px; line-height:1.5; letter-spacing:-.011em;
  font-feature-settings:"cv02","cv03","cv04","cv11","ss01"; -webkit-font-smoothing:antialiased;
  color:hsl(var(--foreground)); background:hsl(var(--background)); overflow-x:hidden }
.backdrop{ position:fixed; inset:0; pointer-events:none;
  background:radial-gradient(900px circle at 15% -10%, hsl(var(--wash-cool)/var(--wash-cool-a)), transparent 60%),
             radial-gradient(800px circle at 100% 110%, hsl(var(--wash-warm)/var(--wash-warm-a)), transparent 60%) }
.corner-round{ corner-shape:round }

.top{ position:absolute; top:16px; left:20px; z-index:2 } .top picture, .top img{ height:30px; display:block }
/* The panel sits right under the logo; the stage is centred in the space left below it. */
.page{ position:relative; flex:1; display:flex; flex-direction:column; align-items:center; padding:calc(72px + env(safe-area-inset-top, 0px)) 16px 16px }
.page .stage{ margin-block:auto }

/* The stage: the game's area, with the score and prompts laid over it */
/* No focus frame on the stage: Space is the game's own control, and the score already shows it has the keys. */
.stage{ position:relative; width:min(760px,100%); height:460px; touch-action:manipulation; user-select:none; -webkit-user-select:none; outline:none }
/* The canvas covers the whole window behind the text, so nothing in flight is cut off at the stage's edge. */
.scene{ position:fixed; inset:0; width:100%; height:100%; z-index:0; pointer-events:none }
.page, .support, .top{ z-index:1 }
.stage .fallback{ position:absolute; inset:0; display:none; place-items:center }
.stage.no-gl .fallback{ display:grid }
.stage.no-gl .prompt, .stage.no-gl .score, .stage.no-gl .best-line{ display:none }
.sr-only{ position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0 }


.score{ position:absolute; top:52px; left:0; right:0; text-align:center; z-index:2; pointer-events:none; opacity:0; transition:opacity .4s }
.score.on{ opacity:1 }
.score b{ display:block; font-size:56px; line-height:1; font-weight:700; letter-spacing:-.04em; font-variant-numeric:tabular-nums }
.score span{ display:block; margin-top:6px; height:18px; font-size:12px; font-weight:700; letter-spacing:.16em; text-transform:uppercase; color:hsl(var(--tone-success)); opacity:0; transition:opacity .2s }
.score span.on{ opacity:1 }

/* After a run the prompt sits above the best score; on the attract screen it has the bottom to itself. */
.prompt.high{ bottom:40px }
.prompt{ position:absolute; bottom:14px; left:0; right:0; text-align:center; z-index:2; pointer-events:none; font-size:12px; font-weight:600;
  letter-spacing:.14em; text-transform:uppercase; color:hsl(var(--muted-foreground)); transition:opacity .3s }
.prompt.blink{ animation:blink 1.2s steps(2,start) infinite }
.prompt.off{ opacity:0; animation:none }
@keyframes blink{ to{ visibility:hidden } }

/* The progress panel: above the game for the whole wait, one fixed height in every state so nothing below it moves.
   It turns into "your agent is ready" at the end and stays. */
.panel{ position:relative; display:flex; align-items:center; gap:14px; width:min(640px,100%); height:76px; margin-bottom:8px; padding:0 16px; overflow:hidden;
  border-radius:20px; background:hsl(var(--card)); box-shadow:var(--shadow-raised) }
.panel .ico{ width:40px; height:40px; flex:none; border-radius:12px; display:grid; place-items:center; background:hsl(var(--well)) }
.panel .ico svg{ width:20px; height:20px }
.panel .ico .loader{ --h:16px }
.panel .body{ min-width:0; flex:1; display:flex; flex-direction:column }
.panel .eyebrow{ font-size:10.5px; font-weight:700; letter-spacing:.14em; text-transform:uppercase; color:hsl(var(--muted-foreground)) }
.panel b{ font-size:15px; font-weight:600; letter-spacing:-.01em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.panel small{ font-size:12.5px; color:hsl(var(--muted-foreground)); white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.panel .end{ flex:none; display:flex; align-items:center }
.panel .pct{ font-size:20px; font-weight:600; letter-spacing:-.02em; font-variant-numeric:tabular-nums }
.panel .bar{ position:absolute; left:0; right:0; bottom:0; height:3px; background:hsl(var(--well)) }
.panel .bar i{ display:block; height:100%; width:0; background:hsl(var(--primary)); transition:width .6s ease, background-color .3s }
.panel .btn{ display:none }
.panel.ok .ico{ background:hsl(var(--status-done)/.14); color:hsl(var(--tone-success)) }
.panel.ok .eyebrow{ color:hsl(var(--tone-success)) }
.panel.ok .pct{ display:none }
.panel.ok .btn{ display:inline-flex }
.panel.ok .bar i{ background:hsl(var(--status-done)) }
.panel.err .ico{ background:hsl(var(--destructive)/.12); color:hsl(var(--tone-danger)) }
.panel.err .eyebrow{ color:hsl(var(--tone-danger)) }
.panel.err .pct{ display:none }
.panel.err .bar i{ background:hsl(var(--destructive)) }
/* The not-found page: one panel alone in the middle, without a progress bar, its text free to wrap. */
.page.lone{ justify-content:center }
.panel.lone{ height:auto; align-items:flex-start; padding:16px; margin-bottom:0 }
.panel.lone b, .panel.lone small{ white-space:normal }
.btn.sm{ height:32px; padding:0 14px; font-size:13px }
@media (max-width:520px){ .panel{ gap:10px; padding:0 12px } .panel .pct{ font-size:16px } }

/* After a run, under the score in cubes: the best so far, above the blinking prompt. */
.best-line{ position:absolute; bottom:14px; left:0; right:0; text-align:center; z-index:2; pointer-events:none; font-size:12.5px; color:hsl(var(--muted-foreground));
  font-variant-numeric:tabular-nums; opacity:0; transition:opacity .3s }
.best-line.on{ opacity:1 }
.best-line b{ color:hsl(var(--foreground)) }
.best-line .new{ display:inline-block; margin-left:6px; padding:1px 8px; border-radius:9999px; font-size:11px; font-weight:700;
  background:hsl(var(--status-done)/.14); color:hsl(var(--tone-success)) }
.btn{ display:inline-flex; align-items:center; justify-content:center; gap:8px; height:40px; padding:0 20px; border:0; border-radius:9999px; cursor:pointer;
  font:inherit; font-size:14px; font-weight:500; background:hsl(var(--primary)); color:hsl(var(--primary-foreground)) }

.support{ position:relative; display:flex; flex-direction:column; align-items:center; text-align:center; padding:16px 16px max(28px, env(safe-area-inset-bottom)); font-size:13px; color:hsl(var(--muted-foreground)) }
.support p{ margin:0 }
/* Three plain lines, one under the other. The first changes with the state, so it keeps one line's height
   (two on phones) and the page never moves the stage. */
.support p{ line-height:1.5 }
.support .lead{ min-height:1.5em; text-wrap:balance }
.support .leave{ margin-bottom:6px }
.support a{ color:inherit }
/* Only a first setup sends the email; elsewhere the line keeps its space and stays hidden. */
.support .leave{ visibility:hidden }
body.can-leave .leave{ visibility:visible }

.loader{ --h:28px; width:calc(var(--h)*1.4); height:var(--h); display:flex; flex-direction:column; justify-content:center; gap:calc(var(--h)*.14) }
.loader i{ display:block; height:calc(var(--h)*.22); border-radius:9999px; transform-origin:left; animation:wave 1.1s ease-in-out infinite }
.loader i:nth-child(1){ background:var(--red-1) } .loader i:nth-child(2){ background:var(--red-2); animation-delay:.14s } .loader i:nth-child(3){ background:var(--red-3); animation-delay:.28s }
@keyframes wave{ 0%,100%{ transform:scaleX(.4); opacity:.45 } 50%{ transform:scaleX(1); opacity:1 } }

@media (prefers-reduced-motion:reduce){ .loader i, .prompt.blink{ animation:none } }
@media (max-width:520px){ .stage{ height:420px } .support .lead{ min-height:3em } .score b{ font-size:44px } .top picture, .top img{ height:24px } }
