/* Protopilot — cockpit bezel shell. The canvas draws the game;
   this file only styles the housing, HUD, overlays and level grid. */

/* Press Start 2P, served from here rather than from Google's CDN.
   SIL Open Font License 1.1, credited in CREDITS in config.js.

   Self-hosted for three reasons, in ascending order of importance. It drops a
   cross-origin round trip on cold start, which a wrapped app pays on every
   launch. It makes dist/protopilot.html genuinely self-contained — that build
   is one file you can email, and until now it quietly lost its typeface
   without a network. And it means loading the game no longer hands a third
   party the IP address of everyone who plays, which was a paragraph the
   privacy policy had to carry and now does not.

   The latin subset only. Its unicode-range covers U+0000-00FF and
   U+2000-206F, which is every glyph the game actually draws — including the
   em dash and ellipsis in the menus. The other four subsets Google serves are
   Cyrillic, Greek and extended Latin, none of which appear anywhere here.

   The path resolves from this file, so src/css/ -> ../../fonts/. build.js
   replaces this whole rule with a base64 copy when it inlines the CSS into the
   single-file build, where a relative URL would resolve against dist/ and
   404. */
@font-face{
  font-family:"Press Start 2P";
  font-style:normal;
  font-weight:400;
  font-display:swap;
  src:url("../../fonts/press-start-2p-latin.woff2") format("woff2");
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root{
    --void:#080D1C;
    --panel:#111A33;
    --bezel:#22315C;
    --amber:#F2B134;
    --cream:#DDE7FA;
    --rust:#D94F3D;
    --dim:#6E7FA6;
    --arcade:"Press Start 2P", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  }
  *{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
  html,body{height:100%;overflow:hidden;background:var(--void)}
  body{
    font-family:var(--arcade);color:var(--cream);
    display:flex;align-items:center;justify-content:center;
    padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
    user-select:none;-webkit-user-select:none;
  }
  #housing{position:relative;width:100%;height:100%;max-width:540px;display:flex;flex-direction:column;background:var(--void)}
  #screen{
    position:relative;flex:1;min-height:0;background:var(--void);overflow:hidden;
    display:flex;align-items:center;justify-content:center;
    border-left:3px solid var(--bezel);border-right:3px solid var(--bezel);
  }
  canvas{display:block;image-rendering:pixelated;image-rendering:crisp-edges;touch-action:none}

  #hud{
    position:absolute;top:0;left:0;right:0;display:flex;justify-content:space-between;
    padding:9px 11px;font-size:9px;line-height:1.9;pointer-events:none;
    text-shadow:0 2px 0 rgba(0,0,0,.6);
  }
  #hud .lbl{display:block;font-size:6px;color:rgba(221,231,250,.62);letter-spacing:.5px}
  #hud .val{color:#fff}
  #hud .right{text-align:right}

  /* The music credit, centred at the top and doubling as the mute button.
     z-index puts it over the overlay sheets: attribution has to be visible on
     the title screen and the leaderboard too, not only while flying. */
  /* The wrapper does the centring, not the button. The global button:active
     rule sets its own transform, which would replace a translateX(-50%) on the
     button and throw the bar sideways mid-press — far enough that the pointer
     left it and the click never completed. Keeping the two jobs on separate
     elements means the press can only ever nudge it down, as intended.
     Sits below the level/speed line: at 375px those blocks leave no room in
     the middle, and attribution that truncates is not attribution. */
  .creditbar{
    position:absolute;top:38px;left:0;right:0;z-index:6;
    display:flex;justify-content:center;pointer-events:none;padding:0 10px;
  }
  .credit{
    display:flex;align-items:center;gap:5px;max-width:100%;
    pointer-events:auto;background:rgba(8,13,28,.55);border:0;border-radius:3px;
    padding:4px 8px;margin:0;cursor:pointer;line-height:1.4;
    font-family:var(--arcade);font-size:6px;letter-spacing:.5px;
    color:var(--cream);opacity:.78;text-align:center;
  }
  .credit:hover{opacity:1}
  .credit svg{flex:none}
  /* Wraps rather than ellipsises. Dropping the licence took the longest credit
     from 299px to 137, which clears the 263 a 320px phone offers, so today
     every track fits on one line. The wrap stays as the fallback for a longer
     title later: a cut-off attribution satisfies nothing. */
  .credit span{text-align:left}
  .credit .cone{fill:currentColor}
  .credit .wave{fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round}
  .credit .slash{display:none;stroke:var(--rust);stroke-width:1.8;stroke-linecap:round}
  .credit[aria-pressed="true"]{opacity:.55}
  .credit[aria-pressed="true"] .wave{display:none}
  .credit[aria-pressed="true"] .slash{display:block}
  /* display:flex would otherwise beat the [hidden] default. */
  .credit[hidden]{display:none}


  .sheet{
    position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:16px;padding:26px 22px;text-align:center;background:rgba(6,10,22,.82);overflow-y:auto;
  }
  .sheet[hidden]{display:none}
  .eyebrow{font-size:7px;letter-spacing:2px;color:var(--amber)}
  h1{font-size:17px;line-height:1.6;font-weight:400}
  h2{font-size:12px;line-height:1.7;font-weight:400}
  .body{font-size:8px;line-height:2.2;color:var(--dim);max-width:28ch}
  .figure{font-size:24px;color:var(--amber);line-height:1.4}
  .figure small{display:block;font-size:7px;color:var(--dim);letter-spacing:1.5px;margin-top:8px}
  .pair{display:flex;gap:22px;justify-content:center;flex-wrap:wrap}
  .pair div{font-size:11px;color:var(--cream)}
  .pair span{display:block;font-size:6px;color:var(--dim);letter-spacing:1px;margin-top:6px}
  .row{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}

  /* A highlight that sweeps across the title, the way a coin catches the light.
     It's a gradient clipped to the glyphs and slid sideways — the text stays
     selectable, readable and one element, unlike the usual trick of stacking a
     second copy under a masked overlay.

     Behind @supports because background-clip:text is what makes it work: where
     it isn't understood the colour:transparent below would take the title with
     it and leave a blank screen where the name should be. Cream either side of
     the band so the glyphs sit at their normal colour for most of the cycle and
     the amber only passes through. */
  @supports ((background-clip: text) or (-webkit-background-clip: text)){
    #sTitle h1{
      background:linear-gradient(100deg,
        var(--cream) 0%, var(--cream) 42%,
        #FFFFFF 47%, var(--amber) 50%, #FFFFFF 53%,
        var(--cream) 58%, var(--cream) 100%);
      background-size:300% 100%;
      background-position:150% 0;
      -webkit-background-clip:text;
      background-clip:text;
      color:transparent;
      animation:shine 4.5s linear infinite;
    }
  }
  @keyframes shine{ to{ background-position:-50% 0 } }
  /* Must follow the block above: same specificity, so source order is what
     lets it win. Parks the gradient on its cream end rather than mid-sweep. */
  @media (prefers-reduced-motion: reduce){
    #sTitle h1{animation:none;background-position:0 0}
  }

  /* Credits. Scrolls on its own so a long playlist can't push the BACK button
     off the bottom of a short screen. */
  #creditList{
    width:100%;max-width:320px;max-height:56vh;overflow-y:auto;text-align:left;
  }
  .credit-head{
    font-size:7px;letter-spacing:2px;color:var(--amber);
    margin:14px 0 6px;
  }
  .credit-head:first-child{margin-top:0}
  .credit-row{font-size:8px;line-height:2;color:var(--dim)}
  .credit-row a{color:var(--cream);text-decoration:underline}
  .credit-row a:hover{color:var(--amber)}
  .credit-row em{font-style:normal;color:var(--cream)}

  /* Dismiss, in the corner of a sheet. Deliberately quiet and deliberately
     large to hit: declining should cost one tap, not a moment's aiming. */
  .close{
    position:absolute;top:6px;right:8px;
    background:none;border:0;padding:0;
    /* 44px square: the smallest comfortable touch target. Quiet to look at,
       but declining must never take two attempts. */
    width:44px;height:44px;
    display:flex;align-items:center;justify-content:center;
    font-size:17px;line-height:1;color:var(--dim);
  }
  .close:hover{color:var(--cream)}

  /* The dealt name. Smaller than .figure's 24px because two words need the
     room, and boxed so it reads as a thing being offered rather than a title. */
  #nameOffer{
    font-size:13px;line-height:1.5;color:var(--cream);
    background:var(--panel);border:2px solid var(--bezel);border-bottom-width:4px;
    border-radius:3px;padding:14px 16px;max-width:280px;
  }
  #nameNote.bad{color:var(--rust)}

  /* Sign-in trouble, on the title screen. Rust rather than the muted grey the
     rest of .body uses: this is the one message here the player has to read. */
  .warn{color:var(--rust)}
  .warn[hidden]{display:none}

  button{
    font-family:var(--arcade);font-size:9px;color:#2A1704;background:var(--amber);
    border:0;border-bottom:4px solid #A9761B;border-radius:3px;padding:13px 18px;cursor:pointer;letter-spacing:.5px;
  }
  button.ghost{background:transparent;color:var(--dim);border:2px solid var(--bezel);border-bottom-width:4px}
  /* The one button in the game that destroys something. Rust rather than amber
     so it cannot be pressed on muscle memory built on every other primary
     button — it should not look like the thing you always tap. */
  button.danger{color:#FFEDE9;background:var(--rust);border-bottom:4px solid #8E2F22}
  /* Held down for the length of the round trip, so a slow connection can't
     collect a second tap. Nothing else here is ever disabled. */
  button:disabled{opacity:.5;cursor:default;transform:none}
  button:active:not(:disabled){transform:translateY(2px);border-bottom-width:2px}
  button:focus-visible{outline:3px solid #fff;outline-offset:3px}

  #grid{display:grid;grid-template-columns:repeat(5,1fr);gap:7px;width:100%;max-width:290px}
  .lv{
    aspect-ratio:1;border-radius:3px;border:2px solid var(--bezel);background:var(--panel);
    color:var(--cream);font-family:var(--arcade);font-size:11px;cursor:pointer;
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;padding:0;
    border-bottom-width:4px;
  }
  .lv em{font-style:normal;font-size:5px;color:var(--amber);letter-spacing:.5px}
  .lv.lock{color:#33406A;border-color:#1A2444;background:#0C1428;cursor:not-allowed}
  .lv.done{border-color:var(--amber)}

  /* Leaderboard. Fixed-width rank and score columns so the names line up
     however long they are, and the name itself truncates rather than wraps. */
  /* Your own total, coin first. Same markup on the title screen and the level
     select so the two always read identically. */
  .score{
    display:flex;align-items:center;justify-content:center;gap:7px;
    font-size:14px;color:var(--amber);line-height:1;
  }
  .score svg{display:block;image-rendering:pixelated;flex:none}

  #bdList{
    list-style:none;width:100%;max-width:320px;display:flex;flex-direction:column;gap:2px;
    /* Tall enough that all ten fit without scrolling on a normal phone; it
       still scrolls rather than overflowing on a very short screen. */
    max-height:46vh;overflow-y:auto;
  }
  /* Sign in/out sits at the foot of the title screen, pushed there by an auto
     top margin. On its own that margin swallows *all* the slack, which beats
     justify-content:center and pins the title to the top — so the heading
     carries a matching auto margin and the free space splits evenly between
     them. Title and buttons end up centred, sign-out still at the bottom. */
  #sTitle h1{margin-top:auto}
  .foot{margin-top:auto}
  .foot[hidden]{display:none}
  #bdList li{
    display:flex;align-items:center;gap:10px;padding:8px 9px;font-size:8px;
    background:var(--panel);border:1px solid var(--bezel);border-radius:2px;color:var(--cream);
    /* Fixed, so the sprite badges on the top three cannot make those rows
       taller than the numbered ones. box-sizing is global, so this includes
       the padding and border. */
    height:28px;
  }
  #bdList li.you{border-color:var(--amber);background:#1A2447}
  #bdList b{width:22px;color:var(--dim);font-weight:400;text-align:right;flex:none}
  /* The podium badges are sprites, so keep the pixels hard-edged and centre
     them in the same column the numbers use — the rows must not shift. */
  #bdList b.medal{display:flex;align-items:center;justify-content:flex-end}
  #bdList b.medal svg{display:block;image-rendering:pixelated}
  #bdList span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #bdList i{font-style:normal;color:var(--amber);flex:none}
  #bdList em{font-style:normal;font-size:6px;color:var(--dim);flex:none}

  @media (prefers-reduced-motion: reduce){ *{transition:none!important} }
