/* Pledge Rain - hangar-defense arcade game (own page, public).
   Ported from the standalone pledge-rain.html submission into the site's
   page shape. Kept as one big page-specific stylesheet (like retrofitter.css)
   rather than broken up, since almost none of it is reused elsewhere.

   Differences from the submitted file, and why:
   - The game was written as a full standalone document (:root vars, and
     html/body rules covering the whole page). This page now shares html/body
     with the site's nav+footer chrome, so those rules move onto
     #pledgeRainStage (the game's own full-viewport stage element) instead,
     and the universal `*` reset is scoped to `.pledge-rain-page *` so it
     doesn't strip margin/padding off the shared nav/footer. The class-based
     scope is deliberate: using `#pledgeRainStage *` gave the reset ID-level
     specificity, which overrode later `.card`, `.rules` and `button.cta`
     padding/margins and made the menu panels/buttons sit flush to their
     content/parent edges.
   - #pledgeRainStage is `position:fixed; inset:0` with a z-index above the
     site nav (nav.css's .site-nav is z-index:1000), so the game still fills
     the whole screen exactly as submitted - nav/footer are present in the
     DOM (fetched the same way every other page does) but sit underneath the
     game while it's running. Getting back to the rest of the site happens
     through the game's own Escape -> pause -> Quit flow (see pledge-rain.js),
     which is why that requirement mattered enough to ask about explicitly.
   - Colours: --gold/--gold-dim (not part of the site's palette at all - see
     css/root.css) are replaced with the site's real --highlight-colour /
     --main-colour1 tokens, and --line/--panel get an explicit theme-alt
     override, so toggling the site's existing theme button (blue/red)
     reskins the game too, the same way every other page already works.
     --red/--green are left as literal hex - those are semantic
     success/danger colours for game events (ship denied vs. debuff picked
     up), not site branding, so they don't need to track the theme. */
#pledgeRainStage {
  --bg: var(--background-dark);
  --cyan: var(--highlight-colour);
  --cyan-hot: var(--glow-colour);
  --gold: var(--highlight-colour);
  --gold-dim: var(--main-colour1);
  --red: #ff5a6a;
  --green: #5dffb1;
  --panel: rgba(4, 12, 28, 0.78);
  /* Still used by the in-game HUD (.stat/.fxchip/etc. below) - the overlay
     MENU screens (.card and everything inside it) no longer use --line at
     all as of 2026-09-19's members-container redo; see the big comment
     above .card for why. */
  --line: rgba(79, 195, 255, 0.28);
  /* HUD-only secondary/label text colour (site-wide CSS review, 2026-09-19).
     Was a flat hardcoded blue (#7aa3c4/#9ecdeb) that stayed blue even under
     the site's red theme, while every other HUD colour here already
     switches via --cyan/--gold. Deriving it from --highlight-colour instead
     - the same discipline retrofitter.css/commodities.css use for their own
     extra tokens - makes it track the theme automatically with no separate
     .theme-alt override needed. */
  --muted: color-mix(in srgb, var(--highlight-colour) 55%, white);

  position: fixed;
  inset: 0;
  z-index: 1500;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: #e8f4ff;
  font-family: Arial, Helvetica, sans-serif;
  cursor: default;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
}
body.theme-alt #pledgeRainStage {
  --panel: rgba(28, 4, 4, 0.78);
  --line: rgba(255, 75, 75, 0.20);
}
.pledge-rain-page,
.pledge-rain-page * {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
canvas { display: block; width: 100%; height: 100%; }
#hud, #overlay, #receipts, #noCursor { pointer-events: none; }
    #hud, #overlay, #receipts, #noCursor { pointer-events: none; }
    #hud { position: fixed; inset: 0; z-index: 5; }
    .topbar {
      position: absolute; top: 0; left: 0; right: 0;
      display: flex; align-items: center; justify-content: space-between;
      padding: 14px 22px 10px;
      background: linear-gradient(180deg, rgba(0,0,0,.72), transparent);
    }
    .brand { display: flex; align-items: center; gap: 12px; }
    .brand img { width: 52px; height: 52px; object-fit: contain; display: block; background: transparent; filter: drop-shadow(0 0 8px #4fc3ff); }
    .brand h1 {
      font-family: 'Obsidian', Arial, sans-serif;
      font-size: 18px; letter-spacing: .22em;
      text-transform: uppercase; color: #fff;
      line-height: 1.15;
    }
    .brand h1 span { display: block; color: var(--cyan); font-size: 13px; letter-spacing: .32em; font-weight: 500; }
    .stats { display: flex; gap: 18px; align-items: stretch; }
    .stat {
      min-width: 150px;
      background: var(--panel);
      border: 1px solid var(--line);
      border-radius: var(--radius1);
      padding: 8px 16px 9px;
      backdrop-filter: blur(8px);
    }
    .stat .lbl {
      font-family: Arial, Helvetica, sans-serif;
      font-size: 12px; letter-spacing: .18em;
      color: var(--muted); text-transform: uppercase;
    }
    .stat .val {
      font-family: 'Obsidian', Arial, sans-serif;
      font-size: 24px; color: #fff;
    }
    .stat.wallet .val { color: var(--gold); }
    .stat.wallet.flash .val { color: var(--red); }
    .stat.saved .val { color: var(--green); }
    #fxBar {
      position: absolute; left: 16px; top: 92px;
      display: flex; flex-direction: column; gap: 6px;
      max-width: 280px;
    }
    .fxchip {
      font-family: Arial, Helvetica, sans-serif;
      font-size: 13px;
      letter-spacing: .06em;
      padding: 6px 10px;
      border: 1px solid var(--line);
      border-radius: var(--radius1);
      background: rgba(4, 12, 28, .82);
    }
    .fxchip.up { border-color: rgba(93,255,177,.45); color: #c8ffe6; }
    .fxchip.down { border-color: rgba(255,90,106,.5); color: #ffd0d4; }
    #callout {
      position: absolute;
      top: 88px;
      left: 50%;
      transform: translateX(-50%);
      width: min(920px, calc(100vw - 32px));
      text-align: center;
      pointer-events: none;
      z-index: 8;
      opacity: 0;
      transition: opacity .2s ease;
    }
    #callout.show { opacity: 1; }
    #callout.up .call-name { color: var(--green); }
    #callout.down .call-name { color: var(--red); }
    .call-kind {
      font-family: Arial, Helvetica, sans-serif;
      font-size: 16px;
      letter-spacing: .28em;
      color: var(--muted);
      margin-bottom: 4px;
    }
    .call-name {
      font-family: 'Obsidian', Arial, sans-serif;
      font-size: 42px;
      font-weight: 800;
      letter-spacing: .08em;
      text-transform: uppercase;
      text-shadow: 0 4px 18px rgba(0,0,0,.7);
      line-height: 1.1;
    }
    .call-blurb {
      margin-top: 6px;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 24px;
      font-weight: 700;
      color: #eaf4ff;
      text-shadow: 0 3px 12px rgba(0,0,0,.7);
    }
    @media (max-width: 720px) {
      .call-name { font-size: 26px; }
      .call-blurb { font-size: 16px; }
      #callout { top: 118px; }
    }
    .bottomhint {
      position: absolute; left: 0; right: 0; bottom: 14px;
      text-align: center;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 14px; letter-spacing: .14em;
      color: color-mix(in srgb, var(--muted) 65%, transparent);
    }
    #receipts {
      position: fixed; right: 16px; top: 92px; bottom: 70px;
      width: 280px; overflow: hidden; z-index: 6;
      display: flex; flex-direction: column; justify-content: flex-start; gap: 6px;
    }
    .receipt {
      background: rgba(18, 6, 8, .72);
      border: 1px solid rgba(255, 90, 106, .45);
      border-radius: var(--radius1);
      padding: 8px 12px;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 14px;
      color: #ffd0d4;
      animation: slideIn .25s ease-out, fadeOut 2.8s ease-in 1.4s forwards;
    }
    .receipt.ok {
      background: rgba(4, 22, 16, .72);
      border-color: rgba(93, 255, 177, .4);
      color: #c8ffe6;
    }
    .receipt b { color: #fff; }
    .receipt .amt { color: var(--gold); float: right; }
    .receipt.ok .amt { color: var(--green); }
    @keyframes slideIn { from { transform: translateX(40px); opacity: 0; } to { transform: none; opacity: 1; } }
    @keyframes fadeOut { to { opacity: 0; transform: translateX(16px); } }

    #overlay {
      position: fixed; inset: 0; z-index: 20;
      display: flex; align-items: center; justify-content: center;
      background:
        radial-gradient(ellipse at 50% 18%, rgba(40, 120, 200, .22), transparent 50%),
        rgba(2, 6, 14, .78);
      backdrop-filter: blur(6px);
    }
    #overlay.hidden { display: none; }
    /* 2026-09-19: the menu screens (this .card and everything inside it -
       used for the title, pause, and results overlays) were redone from
       scratch to look like a members-area container instead of a bespoke
       sci-fi HUD panel - i.e. the same visual language as
       members_admin_dashboard.css's .admin-requests-container /
       members_dashboard_layout_default.css's .dashboard-default-container-item
       / member_messages.css's .member-messages-panel: --gradient-light
       background, var(--highlight-colour) border, var(--radius1) corners,
       'Obsidian'/Arial site typography, and site button styling
       (var(--gradient-main) fill, scale+glow hover). The in-game HUD
       (.topbar/.stats/.fxchip/#receipts above) keeps its own bespoke
       layout - it's gameplay chrome, not a "menu", and the site's own
       precedent for bespoke pages like this (retrofitter.css,
       commodities.css, css/members_mining.css) is to keep that layout
       rather than reskin it as a member panel. What DID change there in
       the 2026-09-19 site-wide CSS review: the Orbitron/Rajdhani/Share
       Tech Mono Google Fonts import was dropped for the site's own
       Obsidian/Arial pairing (matching what retrofitter.css/
       commodities.css already did), --line/--panel/--cyan/--gold stay as
       the HUD's own scoped tokens, .stat/.fxchip/.receipt picked up
       var(--radius1) corners (every other bespoke instrument-panel page's
       stat chips already round theirs), and a new --muted token derives
       the HUD's secondary/label text colour from --highlight-colour so it
       reacts to the blue/red theme toggle like the rest of the page
       already does, instead of staying hardcoded blue. None of
       pledge-rain.js's game logic, leaderboard behaviour, or button
       text/functionality was touched - this is a CSS-only pass. */
    /* 2026-09-19: full reset. Several rounds of one-off "add more space
       here" tweaks had pushed this screen's proportions well past anything
       else on the site (padding/margins in the 3-6rem range vs. the 0.5-
       1.5rem the rest of the members area actually uses), so instead of
       tuning individual values again this is rebuilt directly off the
       site's real shared container classes:
         - outer panel   = member_messages.css's .member-messages-panel
           (gradient-light background, highlight-colour border, radius1
           corners, a flat 1.5rem padding)
         - sub-panels    = .member-message-item / .admin-request-item
           (background-dark fill, a subtle rgba(255,255,255,.1) border,
           radius1 corners, ~0.75-1rem padding, divided rows)
         - paired buttons = competitions.css's .competition-admin-actions
           button (two compact buttons side by side - gradient-main fill,
           highlight-colour border, radius1 corners, Obsidian font, scale+
           glow hover), not forms.css's larger single-CTA button
         - vertical rhythm = the same modest 0.5-1.5rem gaps those
           stylesheets use throughout, not a bespoke oversized scale.
       The in-game HUD (.topbar/.stats/.fxchip/#receipts above) is
       untouched - it's gameplay chrome, not a "menu". None of
       pledge-rain.js's game logic, leaderboard behaviour, or button
       text/functionality changed - CSS only. */
    .card {
      width: min(640px, calc(100vw - 32px));
      max-height: calc(100vh - 48px);
      overflow-y: auto;
      background-image: var(--gradient-light);
      border: 0.125rem solid var(--highlight-colour);
      border-radius: var(--radius1);
      padding: 1.5rem;
      text-align: center;
      pointer-events: auto;
      font-family: Arial, Helvetica, sans-serif;
    }
    .card h2 {
      font-family: 'Obsidian', Arial, sans-serif;
      font-size: 1.8rem;
      letter-spacing: .06em;
      text-transform: uppercase;
      margin: 0;
    }
    .card h2 em { font-style: normal; color: var(--highlight-colour); }
    /* Matches the site's hero-subtitle convention (root.css's
       `main.site-content > h1 + p`): highlight-colour, uppercase, wide
       letter-spacing, ordinary body font rather than a monospace HUD font. */
    .tag {
      margin-top: .5rem;
      font-family: Arial, Helvetica, sans-serif;
      font-size: .9rem; letter-spacing: .16em;
      color: var(--highlight-colour); text-transform: uppercase;
    }
    .card p {
      margin: 1rem 0;
      color: #fff;
      font-size: 1.15rem; line-height: 1.6;
    }
    /* 2026-09-19: gives the intro/results paragraph its own inset sub-panel
       instead of sitting flush in .card - the same "outer container padded
       from an inner bordered box" relationship the site's own Submissions
       Inbox uses (competitions.css's .competition-list-panel around each
       .competition-entry-card): same background-dark/border/radius1 as
       .rules and .board, just without their divided-row treatment since
       this is prose, not a list. .card p's own rule above still controls
       the text's colour/size/line-height through the wrapper. */
    .card-desc {
      margin: 1rem 0;
      border: 1px solid rgba(255,255,255,.1);
      border-radius: var(--radius1);
      background: var(--background-dark);
      padding: .75rem 1rem;
    }
    .card-desc p { margin: 0; }
    /* Wraps the Leaderboards toggle button on both the title and results
       screens - just a bit of breathing room under .tag before it. */
    .board-toggle-row { margin: 1rem 0; }
    /* Leaderboard board(s) are fetched/rendered eagerly as soon as the card
       is shown (unchanged), but stay visually collapsed until the
       Leaderboards button reveals them (2026-09-19: moved out of the
       always-visible flow and behind a toggle, since the boards took up
       the same prime real estate as the description). */
    .boards.hidden { display: none; }
    /* Same divided-row list convention as .admin-requests-list /
       .admin-request-item, with real bullet markers (list-style-position:
       inside keeps the glyph inside the li's own padding box instead of
       sitting on/outside the panel's edge - the fix used back in Round 2). */
    .rules {
      text-align: left; margin: 1rem 0;
      border: 1px solid rgba(255,255,255,.1);
      border-radius: var(--radius1);
      background: var(--background-dark);
      font-size: 1.15rem; color: #fff;
      list-style: disc;
      list-style-position: inside;
    }
    .rules li { padding: .75rem 1rem; border-bottom: 1px solid rgba(255,255,255,.08); line-height: 1.5; }
    .rules li:last-child { border-bottom: none; }
    .rules li::marker { color: var(--highlight-colour); }
    .rules b { color: var(--highlight-colour); }
    /* 2026-09-19: resized to match the members dashboard cards' own button
       links (.form-container-item button/a in
       members_dashboard_layout_default.css: padding 0.7rem 1rem, font-size
       1.25rem) at the site owner's explicit request, replacing the earlier
       Round 8 sizing modelled on competitions.css's smaller paired-button
       convention. */
    button.cta {
      pointer-events: auto;
      cursor: pointer;
      border: 0.125rem solid var(--highlight-colour);
      border-radius: var(--radius1);
      background: var(--gradient-main);
      color: #fff;
      font-family: 'Obsidian', Arial, sans-serif;
      font-size: 1.25rem;
      padding: .7rem 1rem;
      text-transform: uppercase;
      transition: transform .3s ease, box-shadow .3s ease;
    }
    button.cta:hover { transform: scale(1.05); box-shadow: 0 0 10px var(--glow-colour); }
    button.cta.ghost { background: transparent; }
    .actions { display: flex; gap: .75rem; justify-content: center; flex-wrap: wrap; margin-top: 1rem; }
    .joinrow {
      display: flex; gap: .5rem; justify-content: center; margin: 1rem 0;
    }
    /* The member's real leaderboard username (decided server-side in
       scripts/pledge_rain_api.php) - guests get nothing in this slot at all
       (site owner's request, 2026-09-19): there's no callsign input any
       more, and a guest's name doesn't exist until the server mints a fresh
       GUEST###### at score-submit time, so there's nothing truthful to show
       or type beforehand. Styled as a small badge in the same subtle-border
       style as .rules/.board rather than the old HUD-style input-shaped box. */
    /* 2026-09-19: resized to match button.cta's own dashboard-card-link
       scale (site owner's explicit request), with the width cap nudged up
       to fit "PILOT: <name>" at the larger font without wrapping. */
    .pilot-tag {
      width: min(320px, 85%);
      border: 1px solid rgba(255,255,255,.15);
      border-radius: var(--radius1);
      background: var(--background-dark);
      color: #fff;
      font-family: 'Obsidian', Arial, sans-serif;
      text-align: center;
      font-size: 1.25rem;
      padding: .7rem 1rem;
      margin: 1rem auto;
    }
    .pilot-tag b { color: var(--highlight-colour); }
    /* Two separate boards (members / guests - see js/pledge-rain.js's
       boardMarkup()), each styled like .member-message-item: a bordered
       panel with a centred 'Obsidian' heading separated from its rows by a
       border-bottom, and rows separated from each other the same way
       .admin-request-item rows are. */
    .boards { margin: 1rem 0; display: flex; flex-direction: column; gap: 1rem; }
    .board {
      text-align: left;
      margin: 0;
      border: 1px solid rgba(255,255,255,.1);
      border-radius: var(--radius1);
      background: var(--background-dark);
    }
    .board h3 {
      font-family: 'Obsidian', Arial, sans-serif;
      font-size: 1rem;
      letter-spacing: .04em;
      color: var(--highlight-colour);
      text-align: center;
      padding: .75rem 1rem;
      margin: 0;
      border-bottom: 1px solid rgba(255,255,255,.1);
    }
    .board ol { list-style: none; margin: 0; padding: 0; }
    .board li {
      display: flex; justify-content: space-between; gap: .5rem;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 1rem;
      color: #fff;
      padding: .75rem 1rem;
      border-bottom: 1px solid rgba(255,255,255,.06);
    }
    .board li:last-child { border-bottom: none; }
    .board li .who { color: #fff; font-weight: bold; }
    .board li .n { color: var(--green); }
    .board .empty { color: rgba(255,255,255,.5); font-size: .95rem; padding: .75rem 1rem; text-align: center; }
    #pauseBtn {
      pointer-events: auto;
      cursor: pointer;
      min-width: 110px;
    }
    #pauseLayer {
      position: fixed; inset: 0; z-index: 30;
      display: none;
      align-items: center; justify-content: center;
      background: rgba(2,6,14,.72);
      backdrop-filter: blur(6px);
    }
    #pauseLayer.show { display: flex; }
    body.playing.paused { cursor: default; }
    body.playing.paused #noCursor { display: none; }
    .fine {
      margin-top: 1.5rem;
      font-family: Arial, Helvetica, sans-serif;
      font-size: .85rem; color: #6e8aa3; letter-spacing: .04em;
    }
    body.playing { cursor: none; }
    #noCursor {
      position: fixed; left: 0; top: 0;
      width: 76px; height: 76px;
      z-index: 40;
      display: none;
      transform: translate(-50%, -50%);
      filter: drop-shadow(0 4px 8px rgba(0,0,0,.55));
    }
    body.playing #noCursor { display: block; }
    #noCursor.whack { animation: whack .16s ease-out; }
    @keyframes whack {
      0% { transform: translate(-50%, -50%) scale(1.22) rotate(-12deg); }
      100% { transform: translate(-50%, -50%) scale(1) rotate(0); }
    }
    /* 2026-09-19: now that .card's own scale is the same modest 0.5-1.5rem
       rhythm the rest of the members area uses (see the big comment above
       .card), it doesn't need much reducing for mobile - just the same
       light touch competitions.css's own @media (max-width: 700px) block
       uses. The in-game HUD tweaks below (.stats/.stat/.brand/#receipts)
       are unrelated to the menu and untouched. */
    @media (max-width: 720px) {
      .stats { gap: 8px; }
      .stat { min-width: 96px; padding: 6px 8px; }
      .stat .val { font-size: 18px; }
      .brand h1 { font-size: 13px; }
      .brand h1 span { font-size: 10px; }
      #receipts { display: none; }
      .card { padding: 1.25rem; }
      .card h2 { font-size: 1.4rem; }
      .card p { font-size: 1rem; }
      .actions { gap: .5rem; }
      button.cta { font-size: 1.05rem; padding: .6rem .9rem; }
      .pilot-tag { font-size: 1.05rem; padding: .6rem .9rem; width: min(260px, 85%); }
    }
    /* 2026-09-22 (Matt approved): on phones and small tablets the HUD row
       was wider than the screen, so the score, wave and Pause sat off the
       right edge. Below 960px the stats drop under the logo and share the
       full width; nothing else about the look changes. */
    @media (max-width: 960px) {
      .topbar { flex-wrap: wrap; gap: 8px; padding: 10px 12px 8px; }
      .stats { width: 100%; gap: 8px; }
      .stats .stat { flex: 1 1 0; min-width: 0; padding: 6px 8px; }
      #pauseBtn { min-width: 0; }
      #fxBar { top: 150px; }
      #callout { top: 160px; }
    }
    @media (max-width: 480px) {
      .brand img { width: 40px; height: 40px; }
      .stat .lbl { font-size: 10px; letter-spacing: .1em; }
      .stat .val { font-size: 16px; }
    }
