      :root {
        /* Base ramp */
        --base-50: #ffffff;
        --base-100: rgba(255, 255, 255, 0.05);
        --base-200: rgba(255, 255, 255, 0.1);
        --base-400: #575260;
        --base-600: #363042;
        --base-700: #1e1435;
        --base-800: #120c20;
        --base-900: #0b0713;
        --text-muted: #7d7d7d;

        /* Primary ramp */
        --primary-50: #fa7800;
        --primary-100: #ffe28a;
        --primary-200: #ffdea5;

        /* Gradients */
        --grad-orange-50: linear-gradient(90deg, #fa7800 0%, #ffe28a 100%);
        --grad-orange-400: linear-gradient(90deg, #ffe28a 0%, #fa7800 50%, #ffe28a 100%);
        --grad-white-200: linear-gradient(
          360deg,
          rgba(255, 255, 255, 0.25) 0%,
          rgba(255, 255, 255, 0) 80%
        );

        --danger: #ff6b6b;
      }

      * {
        box-sizing: border-box;
      }

      html {
        scroll-behavior: smooth;
      }

      html,
      body {
        margin: 0;
        min-height: 100%;
        max-width: 100%;
      }

      /*
       * Nothing here is ever meant to scroll sideways. This is only a
       * backstop — the rules below are what actually keep content in bounds.
       * Deliberately on <body> and not <html>: making the root a scroll
       * container upsets anchor scrolling and sticky positioning on iOS.
       */
      body {
        overflow-x: hidden;
      }

      img,
      svg {
        max-width: 100%;
      }

      body {
        background:
          radial-gradient(100% 60% at 50% 0%, rgba(30, 20, 53, 0.9) 0%, transparent 70%),
          var(--base-900);
        color: var(--base-50);
        font-family: Sora, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
        font-size: 14px;
        line-height: 22px;
        -webkit-font-smoothing: antialiased;
        -webkit-tap-highlight-color: transparent;
      }

      button,
      input {
        font: inherit;
        color: inherit;
      }

      /* ===================================================================
       * Cover — the full-viewport entry point.
       *
       * The dealer photo sits under a scrim that fades to --base-900 at the
       * bottom, so the cover melts into the lobby instead of ending on a
       * hard edge. With the image missing the scrim alone still reads as a
       * deliberate dark hero, so the page never looks broken.
       * =================================================================== */

      .cover {
        position: relative;
        min-height: 100vh;
        min-height: 100dvh;
        display: flex;
        align-items: center;
        justify-content: center;
        text-align: center;
        padding: 48px 20px 40px;
        overflow: hidden;
      }

      .cover__photo {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        /* Keeps the dealer's face in frame when the viewport goes portrait. */
        object-position: 50% 20%;
        z-index: 0;
      }

      .cover__scrim {
        position: absolute;
        inset: 0;
        z-index: 1;
        background:
          linear-gradient(
            180deg,
            rgba(11, 7, 19, 0.75) 0%,
            rgba(11, 7, 19, 0.4) 32%,
            rgba(11, 7, 19, 0.88) 76%,
            var(--base-900) 100%
          ),
          radial-gradient(72% 52% at 50% 42%, transparent 0%, rgba(11, 7, 19, 0.6) 100%);
      }

      .cover__inner {
        position: relative;
        z-index: 2;
        max-width: 560px;
        width: 100%;
      }

      .cover__logo {
        display: block;
        width: 260px;
        max-width: 78vw;
        height: auto;
        margin: 0 auto 18px;
        filter: drop-shadow(0 8px 32px rgba(0, 0, 0, 0.6));
      }

      .cover__sub {
        color: rgba(255, 255, 255, 0.75);
        font-size: 16px;
        line-height: 24px;
        margin: 0 0 30px;
      }

      .btn-play {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: min(240px, 100%);
        max-width: 100%;
        background: var(--grad-orange-50);
        color: var(--base-900);
        border: none;
        border-radius: 14px;
        padding: 18px 32px;
        font-family: Orbitron, sans-serif;
        font-weight: 900;
        font-size: 18px;
        line-height: 18px;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        text-decoration: none;
        cursor: pointer;
        box-shadow: 0 10px 40px rgba(250, 120, 0, 0.35);
        transition: transform 140ms ease;
      }

      .btn-play:hover {
        transform: translateY(-2px);
      }

      .btn-play:active {
        transform: translateY(0);
      }

      .cover__note {
        color: rgba(255, 255, 255, 0.45);
        font-size: 12px;
        line-height: 18px;
        margin: 24px 0 0;
      }

      /*
       * Returning players get their saved profile right here on the cover,
       * so the common case — "it's me again, deal me in" — is one tap with
       * no scrolling. Hidden entirely until a profile exists.
       */
      .cover__continue {
        margin-top: 26px;
        text-align: left;
      }

      .cover__continue-label {
        font-family: Orbitron, sans-serif;
        font-weight: 900;
        font-size: 12px;
        line-height: 12px;
        letter-spacing: 0.14em;
        text-transform: uppercase;
        color: rgba(255, 255, 255, 0.55);
        text-align: center;
        margin: 0 0 12px;
      }

      /* Sits on the photo, so it needs more body than the in-lobby rows. */
      .cover__continue .player {
        background: rgba(11, 7, 19, 0.62);
        border-color: rgba(255, 255, 255, 0.14);
        backdrop-filter: blur(10px);
        -webkit-backdrop-filter: blur(10px);
      }

      .cover__continue .player:hover,
      .cover__continue .player:focus-visible {
        background: rgba(11, 7, 19, 0.8);
        border-color: rgba(255, 226, 138, 0.5);
      }

      .wrap {
        max-width: 560px;
        margin: 0 auto;
        padding: 8px 16px 64px;
      }

      /* ===== Header ===== */

      header {
        text-align: center;
        margin-bottom: 32px;
      }

      .wordmark {
        width: 148px;
        max-width: 46vw;
        height: auto;
        opacity: 0.9;
        margin-bottom: 20px;
      }

      .logo {
        display: block;
        width: 210px;
        max-width: 68vw;
        height: auto;
        margin: 0 auto 14px;
      }

      .beta-tag {
        display: inline-block;
        font-family: Orbitron, sans-serif;
        font-weight: 900;
        font-size: 14px;
        line-height: 14px;
        letter-spacing: 0.18em;
        text-transform: uppercase;
        background: var(--grad-orange-50);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
        border: 1px solid rgba(250, 120, 0, 0.4);
        border-radius: 999px;
        padding: 7px 16px 6px;
      }

      .tagline {
        margin: 0;
        color: var(--text-muted);
        font-size: 14px;
        line-height: 22px;
      }

      /* ===== Sections ===== */

      section {
        position: relative;
        background: var(--base-700);
        border: 1px solid var(--base-200);
        border-radius: 16px;
        padding: 20px;
        margin-bottom: 16px;
        overflow: hidden;
      }

      /* Gradient/White 200 — top-edge sheen from the design system. */
      section::before {
        content: "";
        position: absolute;
        inset: 0 0 auto;
        height: 120px;
        background: var(--grad-white-200);
        opacity: 0.35;
        transform: rotate(180deg);
        pointer-events: none;
      }

      section > * {
        position: relative;
      }

      h2 {
        font-family: Orbitron, sans-serif;
        font-weight: 900;
        font-size: 14px;
        line-height: 14px;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--base-50);
        margin: 0 0 16px;
      }

      /* ===== Player rows ===== */

      .player {
        display: flex;
        align-items: center;
        gap: 12px;
        width: 100%;
        text-align: left;
        background: var(--base-100);
        border: 1px solid transparent;
        border-radius: 12px;
        padding: 12px 14px;
        margin-bottom: 8px;
        cursor: pointer;
        transition:
          border-color 140ms ease,
          background 140ms ease,
          transform 140ms ease;
      }

      .player:last-child {
        margin-bottom: 0;
      }

      .player:hover,
      .player:focus-visible {
        background: var(--base-200);
        border-color: rgba(255, 226, 138, 0.45);
        outline: none;
      }

      .player:active {
        transform: scale(0.99);
      }

      .avatar {
        flex: 0 0 auto;
        width: 38px;
        height: 38px;
        border-radius: 50%;
        display: grid;
        place-items: center;
        font-family: Orbitron, sans-serif;
        font-weight: 900;
        font-size: 15px;
        color: var(--base-900);
        background: var(--grad-orange-400);
      }

      .player-main {
        flex: 1 1 auto;
        min-width: 0;
      }

      .player-name {
        font-family: Sora, sans-serif;
        font-weight: 700;
        font-size: 16px;
        line-height: 22px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }

      .player-meta {
        font-size: 12px;
        line-height: 18px;
        color: var(--text-muted);
      }

      /*
       * Balances run long (53,400,176.95 RCH) and must not wrap mid-number,
       * so this is the row's rigid part — the name truncates around it.
       * Below 380px it steps down a size so avatar + name + balance still
       * fit a 320px screen.
       */
      .player-balance {
        flex: 0 1 auto;
        font-family: Orbitron, sans-serif;
        font-weight: 700;
        font-size: 14px;
        line-height: 14px;
        color: var(--primary-100);
        white-space: nowrap;
        text-align: right;
      }

      /*
       * On a narrow phone, name + age + balance on one line squeezes the
       * name down to "ben…" and wraps the age onto a second line. Give the
       * name a line of its own and pair the age with the balance beneath it.
       * `display: contents` lets the name and age take part in this grid
       * without needing a different DOM shape per breakpoint.
       */
      @media (max-width: 420px) {
        .player {
          display: grid;
          /* minmax(0, 1fr), not 1fr: an auto-minimum track refuses to shrink
             below its content, which pushed the balance off the row. */
          grid-template-columns: auto minmax(0, 1fr) auto;
          grid-template-areas:
            "avatar name    name"
            "avatar meta    balance";
          align-items: center;
          column-gap: 10px;
          row-gap: 2px;
          padding: 11px 12px;
        }

        .avatar {
          grid-area: avatar;
          width: 34px;
          height: 34px;
          font-size: 14px;
        }

        .player-main {
          display: contents;
        }

        .player-name {
          grid-area: name;
        }

        .player-meta {
          grid-area: meta;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }

        /* "created 2h ago" → "2h ago". The age is the part that matters. */
        .meta-word {
          display: none;
        }

        /* Small enough that even the widest balance on the tenant
           (53,400,176.95 RCH) leaves room for the age beside it. */
        .player-balance {
          grid-area: balance;
          font-size: 12px;
        }
      }

      /* ===== Form controls ===== */

      input[type="text"],
      input[type="search"] {
        width: 100%;
        max-width: 100%;
        background: var(--base-800);
        border: 1px solid var(--base-200);
        border-radius: 12px;
        padding: 13px 14px;
        /*
         * 16px is deliberate. iOS Safari auto-zooms when you focus an input
         * with a smaller font, and that zoom is what produced horizontal
         * scrolling on tap. Fixing the size beats disabling pinch-zoom via
         * maximum-scale, which would hurt anyone who needs to zoom.
         */
        font-size: 16px;
        line-height: 22px;
      }

      input:focus {
        outline: none;
        border-color: rgba(250, 120, 0, 0.6);
      }

      input::placeholder {
        color: var(--text-muted);
      }

      .row {
        display: flex;
        gap: 8px;
        /* On a narrow phone the button drops to its own full-width line
           instead of forcing the row wider than the screen. */
        flex-wrap: wrap;
      }

      .row input {
        flex: 1 1 12ch;
        min-width: 0;
      }

      /* Primary CTA — matches the splash "PLAY NOW" button. */
      .btn {
        flex: 1 0 auto;
        max-width: 100%;
        background: var(--grad-orange-50);
        color: var(--base-900);
        border: none;
        border-radius: 12px;
        padding: 14px 22px;
        font-family: Orbitron, sans-serif;
        font-weight: 900;
        font-size: 14px;
        line-height: 14px;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        cursor: pointer;
      }

      .btn:disabled {
        opacity: 0.5;
        cursor: default;
      }

      /* ===== Misc ===== */

      .hint {
        font-size: 12px;
        line-height: 18px;
        color: var(--text-muted);
        margin: 12px 0 0;
      }

      .hint strong {
        color: var(--primary-200);
        font-weight: 700;
      }

      .msg {
        font-size: 12px;
        line-height: 18px;
        border-radius: 10px;
        padding: 10px 12px;
        margin-top: 12px;
      }

      .msg-error {
        background: rgba(255, 107, 107, 0.12);
        color: var(--danger);
      }

      .results {
        margin-top: 12px;
      }

      .empty {
        color: var(--text-muted);
        font-size: 12px;
        line-height: 18px;
        padding: 4px 2px 10px;
      }

      .skeleton {
        height: 62px;
        border-radius: 12px;
        margin-bottom: 8px;
        background: linear-gradient(
          90deg,
          var(--base-100) 25%,
          var(--base-200) 50%,
          var(--base-100) 75%
        );
        background-size: 200% 100%;
        animation: shimmer 1.2s infinite linear;
      }

      @keyframes shimmer {
        to {
          background-position: -200% 0;
        }
      }

      .hidden {
        display: none !important;
      }

      footer {
        text-align: center;
        color: var(--base-400);
        font-size: 12px;
        line-height: 18px;
        margin-top: 32px;
      }

      /* Full-screen handoff shown while the browser navigates to the game. */
      .handoff {
        position: fixed;
        inset: 0;
        background: var(--base-900);
        display: grid;
        place-items: center;
        text-align: center;
        padding: 24px;
        z-index: 10;
      }

      .handoff-text {
        font-family: Orbitron, sans-serif;
        font-weight: 900;
        font-size: 16px;
        line-height: 24px;
        text-transform: uppercase;
        background: var(--grad-orange-50);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
      }

      .spinner {
        width: 34px;
        height: 34px;
        border: 3px solid rgba(250, 120, 0, 0.25);
        border-top-color: var(--primary-50);
        border-radius: 50%;
        margin: 0 auto 18px;
        animation: spin 0.8s linear infinite;
      }

      @keyframes spin {
        to {
          transform: rotate(360deg);
        }
      }

      /* ===== Mobile type scale ===== */

      @media (max-width: 480px) {
        body {
          font-size: 14px;
          padding: 24px 14px 48px;
        }

        section {
          padding: 18px 16px;
        }

        .player-name {
          font-size: 15px;
        }

        .btn {
          padding: 13px 18px;
        }
      }