📄 src/lib/components/GpsDialog.svelte
<script lang="ts">
  import { gps } from "$lib/gps.svelte";

  let requesting = $state(false);

  function handleGrant() {
    requesting = true;
    gps.grant();
  }
</script>

{#if gps.consent === null}
  <dialog
    {@attach (node) => {
      node.showModal();
      return () => {
        if (node.open) node.close();
      };
    }}
  >
    <div class="panel">
      <div class="title-bar">Record bird locations?</div>
      <p>
        BirdGO can tag each detection with your GPS position. Your location
        never leaves this device.
      </p>
      <div class="actions">
        <button class="primary" onclick={handleGrant} disabled={requesting}>
          {requesting ? "Requesting…" : "Enable GPS"}
        </button>
        <button class="secondary" onclick={() => gps.deny()}>
          Skip for now
        </button>
      </div>
    </div>
  </dialog>
{/if}

<style>
  dialog {
    border: none;
    background: transparent;
    padding: 0;
    max-width: 26rem;
    width: calc(100% - 2rem);
  }

  dialog::backdrop {
    background: rgba(26, 8, 8, 0.65);
  }

  .panel {
    background: var(--bg-paper);
    border: 2px solid var(--bg-near-black);
    border-radius: 8px;
    position: relative;
    overflow: hidden;

    &::before {
      content: "";
      position: absolute;
      inset: 5px;
      border-radius: 4px;
      border: 1.5px dashed var(--accent-amber);
      pointer-events: none;
      z-index: 1;
    }
  }

  .title-bar {
    background: var(--brand-red);
    color: var(--bg-cream);
    padding: 0.6rem 1.25rem;
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    position: relative;

    &::after {
      content: "";
      position: absolute;
      inset: 4px;
      border: 1.5px dashed var(--bg-cream);
      pointer-events: none;
    }
  }

  p {
    padding: 1rem 1.25rem;
    font-size: 0.95rem;
    line-height: 1.5;
  }

  .actions {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 0 1.25rem 1.25rem;
  }

  .primary {
    background: var(--brand-red);
    color: var(--bg-cream);
    border: none;
    border-radius: 8px;
    padding: 0.65rem 1rem;
    font-size: 1rem;
    font-weight: 700;
    font-family: inherit;
    box-shadow: 0 3px 0 var(--bg-near-black);
    cursor: pointer;
    transition: box-shadow 0.1s, transform 0.1s;

    &:active:not(:disabled) {
      transform: translateY(3px);
      box-shadow: none;
    }

    &:disabled {
      opacity: 0.6;
      cursor: default;
    }
  }

  .secondary {
    background: transparent;
    color: var(--bg-near-black);
    border: 2px solid var(--bg-near-black);
    border-radius: 8px;
    padding: 0.65rem 1rem;
    font-size: 1rem;
    font-family: inherit;
    cursor: pointer;
  }
</style>