/* ---------- tokens ---------- */
:root {
  /* colour: black and greys, plus one accent */
  --paper: #fff;
  --ink: #111;
  --grey-1: #3d3d3d;   /* 11:1 on white */
  --grey-2: #5c5c5c;   /* 6.7:1 */
  --grey-3: #6b6b6b;   /* 5.3:1 */
  --icon: #767676;     /* 4.5:1 */
  --hairline: #e6e6e6;
  --accent: #d11a2a;   /* echoes, detected dots, found rings, the Contact label dot (CONFIG uses the same RGB) */

  /* type */
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --text-xs: 12px;
  --text-sm: 13px;
  --text-md: 15px;
  --tracking-wide: 0.08em;

  /* 8 px spacing scale */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 16px;
  --s-4: 24px;
  --s-5: 32px;

  --radius: 12px;
  --shadow: 0 6px 24px rgba(0, 0, 0, .06);
  --fade: 160ms;
  --slide: 300ms;
  --fly-ease: cubic-bezier(.2, .8, .2, 1);
  --tap: 44px;

  /* crosshair-ish ring cursor near the buoy */
  --cursor-ring: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Ccircle cx='12' cy='12' r='7' fill='none' stroke='%23111' stroke-width='1.5'/%3E%3Cpath d='M12 1v5M12 18v5M1 12h5M18 12h5' stroke='%23111' stroke-width='1.5'/%3E%3C/svg%3E") 12 12;
}

* { box-sizing: border-box; }
html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--paper);
  color: var(--ink);
  font: var(--text-md)/1.45 var(--font);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
p { margin: 0; }

/* Without JS only the <noscript> fallback shows. */
.stage { display: none; }
.js .stage { display: block; position: fixed; inset: 0; }

canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

button {
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  touch-action: manipulation;
}
button:focus { outline: none; }
button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ---------- buoy ---------- */
.buoy, .target {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--tap);
  height: var(--tap);
  border-radius: 50%;
}
.buoy {
  cursor: var(--cursor-ring), pointer;
  touch-action: none; /* dragging on iPhone must not scroll the page */
}
.buoy.dragging, .buoy:active { cursor: grabbing; }
.buoy .bob { position: absolute; inset: 0; } /* z bob scales the dot, never the 44 px tap area */
.buoy .dot {
  position: absolute;
  top: 17px;
  left: 17px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--ink);
  animation: breathe 3s ease-in-out infinite;
}
.buoy.still .dot { animation: none; }
@keyframes breathe { 50% { transform: scale(1.15); } }

.hint {
  position: absolute;
  transform: translateY(-50%);
  font-size: var(--text-sm);
  letter-spacing: var(--tracking-wide);
  color: var(--grey-3);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 400ms ease;
}
.hint.flip { transform: translate(-100%, -50%); }
.hint.show { opacity: 1; }

/* ---------- targets ---------- */
.targets { position: absolute; inset: 0; pointer-events: none; }
.target { pointer-events: auto; cursor: pointer; }
.target.found { cursor: default; }
.target[hidden] { display: none; }

/* ---------- found counter (top-left) ---------- */
.counter {
  position: absolute;
  top: max(var(--s-4), env(safe-area-inset-top));
  left: max(var(--s-4), env(safe-area-inset-left));
  font-size: var(--text-sm);
  line-height: 20px;
  letter-spacing: var(--tracking-wide);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--grey-3);
  pointer-events: none;
  z-index: 5; /* above the panel when it sits at the panel's edge */
  transition: left var(--slide) var(--fly-ease);
}
.counter-n { color: var(--accent); font-weight: 600; }
.counter.complete, .counter.complete .counter-n { color: var(--grey-1); }
/* desktop: while the panel is open the counter moves to its right edge */
.panel-open:not(.mobile) .counter { left: calc(var(--panel-width) + var(--s-4)); }

/* ---------- signature (bottom-left) ---------- */
.signature {
  position: absolute;
  left: max(var(--s-4), env(safe-area-inset-left));
  bottom: max(var(--s-4), env(safe-area-inset-bottom));
  max-width: calc(100vw - var(--s-4) - 64px); /* clear of the sound toggle */
  font-size: var(--text-sm);
  line-height: 1.5;
  pointer-events: none;
  transition: bottom var(--slide) var(--fly-ease);
}
.sig-name { font-size: 14px; font-weight: 600; color: var(--grey-1); }
.sig-role { font-size: var(--text-xs); color: var(--grey-2); letter-spacing: var(--tracking-wide); } /* #5c5c5c: 6.7:1 */
.nowrap { white-space: nowrap; } /* line 2 only ever wraps after "Analyst" */
.sig-contact {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  margin: -6px 0 -12px; /* 44 px tap area, text kept close to the lines above */
  font-size: var(--text-sm);
  color: var(--ink);
  letter-spacing: 0.02em;
  pointer-events: auto;
}
.sig-contact:hover, .sig-contact:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
.sig-contact:focus-visible { outline-offset: -2px; }
/* the panel covers the signature while open; on mobile it rises above the tab */
.panel-open .signature { visibility: hidden; }
.mobile.has-tab .signature { bottom: calc(max(var(--s-4), env(safe-area-inset-bottom)) + var(--tab-short) + var(--s-2)); }

/* ---------- Contact panel: left panel (desktop) / bottom sheet (mobile) ---------- */
.panel, .contact-card {
  position: fixed;
  background: var(--paper);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow);
  z-index: 4;
}
.panel {
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--panel-width);
  max-width: 100vw;
  border-width: 0 1px 0 0;
  padding: var(--s-4);
  padding-left: max(var(--s-4), env(safe-area-inset-left));
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: pan-y; /* horizontal swipes reach the swipe-to-close handler */
}
.panel[hidden] { display: none; }
.panel:focus { outline: none; } /* focus lands on the dialog when it opens; its controls show their own rings */
.panel.flying { visibility: hidden; } /* laid out in its dock while the card flies to it */

.card-label {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 600;
  font-variant-caps: all-small-caps;
  letter-spacing: var(--tracking-wide);
  color: var(--ink);
}
.card-label::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}

.sheet-head {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--tap);
  margin: -10px calc(-1 * var(--s-3)) 0 0;
}
.sheet-head .card-label { flex: 1; font-size: 15px; }
.sheet-grab { display: none; }
.close {
  width: var(--tap);
  height: var(--tap);
  flex: none;
  font-size: 22px;
  line-height: 1;
  color: var(--grey-2);
  border-radius: 50%;
}
.close:hover { color: var(--ink); }
.close:focus-visible { outline-offset: -6px; }
.panel-hello { margin: var(--s-2) 0 var(--s-3); font-size: 17px; color: var(--grey-1); }

/* the compact card that appears and flies into the dock */
.contact-card {
  top: 0;
  left: 0;
  width: 200px;
  padding: var(--s-3);
  border-radius: var(--radius);
  pointer-events: none;
  transform-origin: 0 0;
  z-index: 6;
}
.contact-card .panel-hello { margin: var(--s-1) 0 0; font-size: var(--text-md); }

/* contact rows: stacked, a small-caps label above each value */
.contact { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.contact-row { display: block; }
.contact-kind {
  display: block;
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  color: var(--grey-3);
  font-variant-caps: all-small-caps;
  line-height: 1.2;
}
.contact-line { display: flex; align-items: center; gap: var(--s-1); min-height: var(--tap); margin-top: -6px; }
.contact-value {
  font-size: var(--text-md); /* 15 px; never smaller than 14 */
  white-space: nowrap; /* email and phone always on one line */
  hyphens: none;
  overflow-wrap: normal;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--hairline);
  line-height: 1.4;
}
.contact-value:hover { text-decoration: underline; border-bottom-color: transparent; }
.copy-icon {
  width: var(--tap);
  height: var(--tap);
  flex: none;
  display: grid;
  place-items: center;
  color: var(--grey-2);
  border-radius: 50%;
}
.copy-icon:hover { color: var(--ink); }
.copy-icon .copied { font-size: 16px; color: var(--ink); }

/* mobile: the panel is a bottom sheet */
.mobile .panel {
  top: auto;
  right: 0;
  width: auto;
  max-height: var(--sheet-max-h);
  border-width: 1px 0 0;
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 0 var(--s-4) max(var(--s-4), env(safe-area-inset-bottom));
}
.mobile .sheet-head {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--paper);
  padding-top: var(--s-3);
  margin-top: 0;
  touch-action: none; /* swipe down to close */
}
.mobile .sheet-grab {
  display: block;
  position: absolute;
  top: 6px;
  left: 50%;
  width: 36px;
  height: 4px;
  margin-left: -18px;
  border-radius: 2px;
  background: #d6d6d6;
}
.mobile .panel-hello { margin-top: var(--s-1); }

/* ---------- the tab left behind after closing ---------- */
/* Desktop: protrudes 28 × 56 px from the left edge, vertically centred.
   Mobile: 56 × 28 px from the bottom edge, centred. A 44 px tap area. */
.tab {
  position: fixed;
  z-index: 4;
  display: grid;
  place-items: center;
  color: var(--grey-2);
}
.tab[hidden] { display: none; }
.tab::before { /* the visible tab */
  content: "";
  position: absolute;
  background: var(--paper);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow);
}
.tab-chevron { position: relative; font-size: 18px; line-height: 1; }
.tab:hover { color: var(--ink); }
.tab:not(.mobile-tab) {
  left: 0;
  top: calc(50% - var(--tab-long) / 2);
  width: var(--tap);
  height: var(--tab-long);
}
.tab:not(.mobile-tab)::before {
  left: -1px;
  top: 0;
  width: var(--tab-short);
  height: var(--tab-long);
  border-radius: 0 var(--s-2) var(--s-2) 0;
}
.tab:not(.mobile-tab) .tab-chevron { margin-right: calc(var(--tap) - var(--tab-short)); }
.tab:not(.mobile-tab) .tab-chevron::before { content: "›"; }
.mobile-tab {
  bottom: 0;
  left: calc(50% - var(--tab-long) / 2);
  width: var(--tab-long);
  height: var(--tap);
}
.mobile-tab::before {
  left: 0;
  bottom: -1px;
  width: var(--tab-long);
  height: var(--tab-short);
  border-radius: var(--s-2) var(--s-2) 0 0;
}
.mobile-tab .tab-chevron { margin-top: calc(var(--tap) - var(--tab-short)); }
.mobile-tab .tab-chevron::before { content: "⌃"; }
.tab:focus-visible { outline: none; }
.tab:focus-visible::before { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ---------- compass (a static chart annotation) ---------- */
.compass {
  position: absolute;
  top: max(var(--s-4), env(safe-area-inset-top));
  right: max(var(--s-4), env(safe-area-inset-right));
  width: 40px;
  height: 40px;
  pointer-events: none;
}
.compass text {
  font-family: var(--font);
  font-size: 9px;
  letter-spacing: var(--tracking-wide);
  fill: var(--icon); /* #767676: 4.5:1 on white */
}

/* ---------- sound toggle ---------- */
.sound {
  position: absolute;
  right: max(var(--s-2), env(safe-area-inset-right));
  bottom: max(var(--s-2), env(safe-area-inset-bottom));
  width: var(--tap);
  height: var(--tap);
  display: grid;
  place-items: center;
  color: var(--icon);
  border-radius: var(--s-2);
}
.sound .waves { display: none; }
/* on mobile, while the sheet is open, the toggle rises above it */
.mobile.panel-open .sound { bottom: calc(var(--sheet-h, 0px) + var(--s-2)); }
.sound.on .waves { display: inline; }
.sound.on .mute { display: none; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- no-JS fallback ---------- */
.fallback {
  position: fixed;
  inset: 0;
  display: grid;
  place-content: center;
  text-align: center;
  padding: var(--s-3);
}
.fallback h1 { margin: 0 0 var(--s-1); font-size: 22px; font-weight: 600; }
.fallback p { margin: var(--s-1) 0; color: var(--grey-1); }
.fallback a { color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .buoy .dot { animation: none; }
  .hint, .counter, .signature { transition: none; }
}
