@import url('https://fonts.googleapis.com/css2?family=Big+Shoulders:wght@500;700;800&family=Onest:wght@400;500;600;700&family=Spline+Sans+Mono:wght@400;500&display=swap');

/* =====================================================================
   tappedin.gg — PROTOTYPE 9: "PRIME".

   The polish castle. Everything that stuck across eight castles, kept;
   everything rough, refined — words, spacing, focus states, crops.

   THREE PALETTES, one click apart in the header, each an action+live
   pair so the colour keeps its job system:

     VOLTAGE  ultraviolet #8a2bff acts / hyper aqua  #00f0ff is live
     SOLAR    hyper orange #ff5400 acts / solar gold #ffc400 is live
     ACID     neon green   #23f26b acts / chartreuse #c8ff2e is live

   The choice sticks (cookie + localStorage) and follows into the inner
   pages. The question wears the pair as a gradient — the signature.

   Locked branding, constant: ARE YOU TAPPED IN? / "Every game
   community, one place. Bring your people." / TAP IN, uppercase.
   ===================================================================== */

*,*::before,*::after{margin:0;padding:0;box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;}
html,body{overflow-x:clip;}
img{display:block;max-width:100%;}
a{color:inherit;text-decoration:none;}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer;}
ul,ol{list-style:none;}

:root{
  --void:#0a0a10;
  --panel:#12121b;
  --panel-2:#191926;
  --line:#262638;
  --line-soft:#191926;

  /* VOLTAGE — the default pair. */
  --act:#8a2bff;  --act-rgb:138,43,255;  --act-ink:#ffffff;
  --act-hi:#a866ff; --act-deep:#6c1fd6;
  --live:#00f0ff; --live-rgb:0,240,255;

  --text:#f4f3fb;
  --dim:#a09db4;
  --dimmer:#62607c;

  --display:'Big Shoulders',sans-serif;
  --body:'Onest',sans-serif;
  --mono:'Spline Sans Mono',monospace;

  --gut:clamp(20px,4vw,60px);
}
html[data-pal="solar"]{
  --act:#ff5400;  --act-rgb:255,84,0;    --act-ink:#180700;
  --act-hi:#ff7a33; --act-deep:#d64500;
  --live:#ffc400; --live-rgb:255,196,0;
}
html[data-pal="acid"]{
  --act:#23f26b;  --act-rgb:35,242,107;  --act-ink:#001408;
  --act-hi:#5cff93; --act-deep:#12c452;
  --live:#c8ff2e; --live-rgb:200,255,46;
}

body{background:var(--void);color:var(--text);font-family:var(--body);line-height:1.6;-webkit-font-smoothing:antialiased;}
::selection{background:var(--act);color:var(--act-ink);}
a:focus-visible,button:focus-visible{outline:2px solid var(--live);outline-offset:3px;border-radius:4px;}

/* --- shared -------------------------------------------------------- */
.k{display:flex;align-items:center;justify-content:center;gap:9px;font-family:var(--mono);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--dimmer);}
.k-dot{display:block;width:7px;height:7px;border-radius:50%;background:var(--live);box-shadow:0 0 12px rgba(var(--live-rgb),.9);flex:0 0 auto;animation:hum 2.4s ease-in-out infinite;}
@keyframes hum{0%,100%{opacity:.5;}50%{opacity:1;}}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:var(--body);font-weight:700;font-size:14px;padding:11px 22px;border-radius:11px;transition:background .16s ease,color .16s ease,transform .1s ease,box-shadow .2s ease;}
.btn-go{position:relative;overflow:clip;background:var(--act);color:var(--act-ink);text-transform:uppercase;letter-spacing:.06em;box-shadow:0 8px 30px -10px rgba(var(--act-rgb),.6);white-space:nowrap;}
.btn-go:hover{background:var(--act-hi);box-shadow:0 10px 38px -10px rgba(var(--act-rgb),.8);}
.btn-go:active{transform:translateY(1px);background:var(--act-deep);}

.tapfx{position:absolute;border-radius:50%;background:rgba(var(--live-rgb),.4);transform:scale(0);pointer-events:none;animation:tapfx .55s ease-out forwards;}
@keyframes tapfx{to{transform:scale(2.4);opacity:0;}}

/* --- header --------------------------------------------------------- */
.top{position:fixed;inset:0 0 auto 0;z-index:40;display:flex;align-items:center;justify-content:space-between;padding:16px var(--gut);border-bottom:1px solid transparent;transition:background .3s ease,border-color .3s ease;}
.top.stuck{background:rgba(10,10,16,.88);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border-bottom-color:var(--line-soft);}
.mark{display:inline-flex;align-items:center;gap:9px;font-family:var(--display);font-weight:800;font-size:18px;letter-spacing:.07em;color:var(--text);text-transform:uppercase;white-space:nowrap;flex-shrink:0;}
.mark i{display:block;width:12px;height:12px;border-radius:3px;background:linear-gradient(135deg,var(--live) 0%,var(--act) 52%,var(--act-deep) 100%);box-shadow:0 0 14px rgba(var(--act-rgb),.7);flex:0 0 auto;transition:background .25s ease;}
.top-right{display:flex;align-items:center;gap:16px;}
.top-link{display:inline-block;font-size:14px;font-weight:500;color:var(--dim);transition:color .16s ease;}
.top-link:hover{color:var(--text);}

/* The palette switcher: three pairs, live preview, remembered. */
.pal{display:flex;align-items:center;gap:9px;padding:7px 10px;border:1px solid var(--line);border-radius:11px;}
.pal button{display:block;width:15px;height:15px;border-radius:50%;border:2px solid transparent;padding:0;transition:transform .12s ease,border-color .15s ease;}
.pal button:hover{transform:scale(1.18);}
.pal .pal-voltage{background:linear-gradient(135deg,#8a2bff,#6c1fd6);}
.pal .pal-solar{background:linear-gradient(135deg,#ffc400,#ff5400);}
.pal .pal-acid{background:linear-gradient(135deg,#c8ff2e,#23f26b);}
html:not([data-pal]) .pal .pal-voltage,
html[data-pal="solar"] .pal .pal-solar,
html[data-pal="acid"] .pal .pal-acid{border-color:var(--text);}

/* --- THE GATE -------------------------------------------------------- */
.gate{position:relative;isolation:isolate;min-height:100svh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:90px var(--gut) 70px;overflow:clip;cursor:pointer;}

@keyframes gate-scroll-glow{
  0%{opacity:0;}
  15%{opacity:1;}
  50%{opacity:1;transform:translate(-50%,0) scaleY(1.1);}
  100%{opacity:.55;transform:translate(-50%,0) scaleY(1);}
}
.gate::after{
  content:"";position:absolute;bottom:0;left:50%;transform:translate(-50%,0);
  width:min(140vw,1800px);height:38%;z-index:-1;pointer-events:none;
  background:radial-gradient(ellipse 60% 80% at 50% 100%,rgba(var(--act-rgb),.28),rgba(var(--act-rgb),.08) 55%,transparent 80%);
  animation:gate-scroll-glow 2.2s ease-out forwards;
}
@media(prefers-reduced-motion:reduce){.gate::after{animation:none;opacity:.55;}}
.gate::before{content:'';position:absolute;top:46%;left:50%;transform:translate(-50%,-50%);width:min(120vw,1500px);height:70vh;z-index:-1;
  background:
    radial-gradient(ellipse 42% 50% at 30% 52%,rgba(var(--live-rgb),.12),transparent 70%),
    radial-gradient(ellipse 40% 48% at 72% 44%,rgba(var(--act-rgb),.2),transparent 70%);
  filter:blur(46px);transition:background .3s ease;}

.statement{display:block;font-size:clamp(14.5px,1.2vw,17.5px);color:var(--dim);line-height:1.6;max-width:46ch;margin:0 0 30px;}

.ask{display:block;font-family:var(--display);font-weight:800;text-transform:uppercase;margin:0;}
.ask .l1{display:block;font-size:clamp(18px,2.8vw,38px);letter-spacing:.4em;color:var(--dim);margin-bottom:4px;font-weight:500;}
.ask .l2{display:block;white-space:nowrap;font-size:clamp(58px,13vw,190px);line-height:.98;letter-spacing:.01em;
  background:linear-gradient(95deg,var(--live) 0%,var(--act) 34%,var(--act-hi) 96%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  filter:drop-shadow(0 0 28px rgba(var(--act-rgb),.35));}

.invite{display:inline-flex;flex-direction:column;align-items:center;gap:10px;margin-top:44px;font-family:var(--mono);font-size:11.5px;letter-spacing:.3em;text-transform:uppercase;color:var(--dim);transition:color .16s ease;}
.invite:hover{color:var(--text);}
.invite .chev{display:block;width:14px;height:14px;border-right:2px solid var(--live);border-bottom:2px solid var(--live);transform:rotate(45deg);animation:sink 2s ease-in-out infinite;}
@keyframes sink{0%,100%{transform:rotate(45deg) translate(0,0);opacity:.5;}50%{transform:rotate(45deg) translate(4px,4px);opacity:1;}}

/* --- FIND YOUR WORLD ------------------------------------------------- */
.zone{padding:clamp(34px,4.5vw,64px) var(--gut);}
.zone-head{display:flex;align-items:baseline;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-bottom:22px;}
.zone-title{font-family:var(--display);font-weight:800;font-size:clamp(22px,2.8vw,36px);letter-spacing:.05em;text-transform:uppercase;}
.zone-note{display:block;font-size:14px;color:var(--dimmer);max-width:48ch;}

.gridiron{display:grid;gap:14px;grid-template-columns:repeat(4,1fr);}
.gridiron > *{min-width:0;}
.cell{display:block;position:relative;aspect-ratio:4/5;border-radius:14px;overflow:clip;border:1px solid var(--line);background:var(--panel);transition:transform .2s cubic-bezier(.2,.7,.3,1),border-color .2s ease,box-shadow .2s ease;}
/* The image's position, size and focal offset now arrive INLINE from
   axiom_image_frame_style(), so this rule no longer dictates them --
   object-fit:cover could only ever fill-and-crop, which is exactly the
   behaviour that sliced lettering. What stays here is the hover motion.
   NOTE the hover uses the standalone `scale` property rather than
   `transform`: the inline style owns `transform` (it carries the focal
   translate), and an inline declaration beats any stylesheet rule, so a
   hover written as transform:scale() would simply never apply. `scale`
   is a separate property and composes with it. */
.cell img{transition:scale .45s cubic-bezier(.2,.7,.3,1);}
.cell::after{content:'';position:absolute;inset:0;background:linear-gradient(180deg,rgba(10,10,16,.05) 40%,rgba(10,10,16,.9) 88%);}
.cell:hover{transform:translateY(-5px);border-color:var(--act);box-shadow:0 18px 48px -18px rgba(var(--act-rgb),.5);}

/* SCROLL FOCUS -- what near-ness LOOKS like. The engine
   (includes/scroll-focus.php) writes only a number, --near 0..1; this is the
   host deciding the look, because a card's appearance belongs to the page
   that owns the card.

   IT IS PROVABLY INERT AT REST. --near defaults to 0 via @property, every
   alpha below multiplies by it, so with no engine on the page this rule paints
   exactly nothing and the resting cell is byte-for-byte what it always was.

   ON ::before, NOT ON .cell, and that is the whole trick. .cell already
   transitions border-color and box-shadow over .2s, so driving those from a
   60fps loop would start a fresh transition every frame -- lag, mush, and the
   direction-lean rendered invisible. ::before carries no transition, so the
   engine's own easing is the only easing. It also leaves border-color alone,
   so :hover still owns it on desktop and the two can never both be lit.

   DELIBERATELY NOT THE HOVER TREATMENT. Hover lifts the card, scales the art
   and reveals TAP IN -- affordances that promise a press. A scroll promised
   nothing, so this is a ring and an inner bloom only: the card is SEEN, not
   armed. Brandon's rule, 2026-08-23: "we're not selecting the game for them."

   Wears the palette for free: --act-rgb is redefined by html[data-pal], so a
   guest who picked SOLAR gets an orange light with nothing else wired. */
/* ONE RULE FOR EVERY SURFACE THE ENGINE DRIVES. Was .cell::before; became
   [data-sf]::before the day the map joined, 2026-08-23, rather than growing a
   second copy that would have to be kept in step by memory. The engine marks
   what it drives; this decides what driven looks like. A world card and the
   map already shared a 14px radius and the same --line border, so they were
   one component wearing two rules -- Principle 1 was pointing at this before
   anyone asked for it. */
[data-sf]::before{content:'';position:absolute;inset:0;z-index:2;pointer-events:none;border-radius:inherit;
  background:rgba(6,6,12,calc((1 - var(--near,1)) * var(--sf-dim,0)));
  /* INSET ONLY. An outer glow here would be invisible: .cell is overflow:clip,
     so anything painted beyond the radius is cut. Putting the glow on .cell
     instead would work but .cell transitions box-shadow over .2s, and a 60fps
     driver would restart that transition every frame. So the ring and the
     inner bloom carry the brightness -- 2px at full alpha rather than 1px at
     .95, because Brandon read the old one as "too dim" on a real screen and
     the cap was mine: the floor was tied to the sharpness knob. */
  box-shadow:inset 0 0 0 2px rgba(var(--act-rgb),var(--near,0)),
             inset 0 0 36px -6px rgba(var(--act-rgb),calc(var(--near,0) * .8));}

/* THE DIM. Brandon, 2026-08-23: "i like the idea of a dim system where as I
   scroll its not flat this one has a border this one doesnt. i scroll and I
   can see something moving per card." A ring on its own is a binary badge you
   have to look for; what makes the movement legible is the rest of the list
   RECEDING while one card comes forward. The wash above does that, and it
   inverts --near so the focal card clears completely.

   TWO FALLBACKS DOING DIFFERENT JOBS, and neither is decoration:
   --near defaults to 1 INSIDE the dim (not 0 like everywhere else), so a page
   with no engine dims nothing rather than dimming every card permanently.
   --sf-dim defaults to 0 for the same reason from the other direction: the
   engine sets it, so without the engine the whole wash multiplies out.
   Between them this rule cannot darken a card it was never driving. */

/* THE RING WAS BEING PAINTED OVER, not failing to paint. Brandon's phone,
   2026-08-23: "the whole border is not visible as desired." Only the bottom
   strip of the frame showed -- exactly the part Leaflet does not cover.

   Leaflet's .leaflet-container is position:relative with z-index:auto, so it
   creates NO stacking context, and its panes (tile 200, overlay 400, shadow
   500, marker 600, popup 700 -- read off the live DOM, not guessed) escape
   into .tapmap's context and paint above a ::before sitting at z-index 2.

   isolation:isolate gives the container its own context so those panes stay
   inside it. That is the mechanism rather than a magic number: raising our
   z-index above 700 would have worked until Leaflet changed a pane, or a
   plugin added one. Scoped to [data-sf] so it only touches a map this engine
   actually drives -- field-map.php's maps are untouched. Verified after: the
   map centre still hit-tests to .leaflet-container, all four markers present,
   panning and controls unchanged. */
[data-sf] .leaflet-container{isolation:isolate;}

/* HOVER GETS LOUDER, because scroll-focus now runs on every input -- wheel,
   thumb, trackpad -- and a pointer landing on a card has to stay a clearly
   bigger event than the light merely passing through it. Brandon's call,
   2026-08-23: "hover over gets a bit more of a pronounced announcment
   visually that they are hovering". A hovered card is fully undimmed, rings
   brighter than any scroll ever paints it, and keeps the lift and the TAP IN
   reveal it always had -- the affordances that mean press me, which the
   scroll deliberately never borrows. */
.cell:hover{box-shadow:0 24px 66px -16px rgba(var(--act-rgb),.7);}
.cell:hover::before{background:transparent;
  box-shadow:inset 0 0 0 3px rgba(var(--act-hi),1),
             inset 0 0 60px -10px rgba(var(--act-rgb),.9);}
.cell:hover img{scale:1.045;}
/* Unread badge on the hub's own avatar. Positioning context and the
   overflow:visible it needs are set on the real .top-ava rule further down,
   not duplicated here. */
.top-ava-dot{position:absolute;bottom:-3px;left:-3px;min-width:16px;height:16px;padding:0 3px;box-sizing:border-box;border-radius:8px;background:var(--live,#00f0ff);color:#05070d;font-family:var(--mono,monospace);font-size:9.5px;line-height:16px;text-align:center;font-weight:700;z-index:3;pointer-events:none;}
.cell-body{position:absolute;inset:auto 0 0 0;z-index:2;padding:16px;}
/* Was one nowrap line with an ellipsis, which AMPUTATED any long name --
   the D2R card read "DIABLO 2 RESURRECTED REIGN OF TH...". Brandon's Law
   is compact or wrap, never hide, so it now takes a second line and the
   type steps down slightly to give a long name MORE of itself rather than
   less. A short name never reaches line two and is unaffected. The short
   display_name override is the real fix; this is what happens when nobody
   has set one yet. */
.cell-name{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;font-family:var(--display);font-weight:800;font-size:clamp(17px,1.85vw,26px);letter-spacing:.03em;line-height:1.12;text-transform:uppercase;overflow:hidden;}
.cell-meta{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim);margin-top:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.cell-meta b{color:var(--live);font-weight:500;}
.cell-go{position:absolute;top:12px;right:12px;z-index:2;font-family:var(--mono);font-size:9px;letter-spacing:.14em;text-transform:uppercase;background:var(--act);color:var(--act-ink);padding:6px 10px;border-radius:8px;opacity:0;transform:translateY(-5px);transition:opacity .18s ease,transform .18s ease;}
.cell:hover .cell-go{opacity:1;transform:none;}
.cell.soon{opacity:.5;}
.cell.soon:hover{transform:none;border-color:var(--line);box-shadow:none;}
.cell.soon:hover img{scale:1;}
.cell.soon .cell-go{background:var(--panel-2);color:var(--dim);}

/* --- just tapped in -------------------------------------------------- */
.fresh{display:grid;gap:13px;grid-template-columns:repeat(5,1fr);}
.fresh > *{min-width:0;}
.drop{display:block;background:var(--panel);border:1px solid var(--line);border-radius:13px;overflow:clip;transition:transform .16s ease,border-color .16s ease;}
.drop:hover{transform:translateY(-4px);border-color:var(--live);}
.drop-img{display:block;position:relative;aspect-ratio:1;overflow:clip;background:var(--panel-2);}
.drop-img img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .35s ease;}
.drop:hover .drop-img img{transform:scale(1.05);}
.drop-new{position:absolute;top:9px;left:9px;z-index:2;display:inline-block;font-family:var(--mono);font-size:8.5px;letter-spacing:.14em;text-transform:uppercase;background:var(--live);color:#0a0a10;padding:4px 8px;border-radius:6px;font-weight:500;}
.drop-body{display:block;padding:11px 13px 13px;}
.drop-name{display:block;font-weight:600;font-size:14px;letter-spacing:-.01em;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.drop-by{display:block;font-family:var(--mono);font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--dimmer);margin-top:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.drop-by i{font-style:normal;color:var(--live);}

/* --- footer ---------------------------------------------------------- */
.foot{border-top:1px solid var(--line-soft);padding:36px var(--gut) 46px;display:flex;flex-wrap:wrap;gap:22px;align-items:center;justify-content:space-between;}
.foot-links{display:flex;flex-wrap:wrap;gap:18px;font-size:13.5px;font-weight:500;color:var(--dim);}
.foot-links a:hover{color:var(--live);}
.foot-note{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--dimmer);}

/* --- reveal ---------------------------------------------------------- */
.rise{opacity:0;transform:translateY(16px);transition:opacity .5s ease,transform .5s cubic-bezier(.2,.7,.3,1);}
.rise.seen{opacity:1;transform:none;}

/* --- mobile ---------------------------------------------------------- */
@media (max-width:900px){
  .gridiron{grid-template-columns:repeat(2,1fr);}
  .fresh{grid-template-columns:repeat(3,1fr);}
  /* The whole header compacts in this band -- big phones at display
     scaling live here, and until 2026-08-01 it only ever got grid
     columns: the wordmark wrapped, TAP IN broke in two, the switcher
     clipped off the edge (seen on a real phone). */
  .top{padding:12px var(--gut);}
  .top-right{gap:10px;min-width:0;}
  .mark{font-size:16px;}
  .pal{gap:7px;padding:5px 7px;}
  .btn-go{padding:9px 14px;font-size:13px;}
  .game-switcher-trigger{font-size:.78rem;padding:6px 8px;}
  /* Meta lines wrap instead of truncating -- "156 entries · live 1d"
     in full beats "LIVE 1…" every time. */
  .cell-meta{white-space:normal;}
}
@media (max-width:640px){
  .gate{padding:80px var(--gut) 56px;}
  .statement{font-size:14px;margin-bottom:24px;}
  .ask .l1{font-size:15px;letter-spacing:.3em;}
  .ask .l2{font-size:clamp(48px,15vw,68px);}
  .invite{margin-top:36px;font-size:10.5px;}
  .game-switcher-trigger .gsw-full{display:none;}
  .game-switcher-trigger .gsw-short{display:inline;}
  .gridiron{gap:11px;}
  .fresh{grid-template-columns:repeat(2,1fr);gap:10px;}
  .cell-body{padding:12px;}
  .zone-head{margin-bottom:16px;}
}
@media (max-width:520px){
  /* True phone widths: EVERYTHING stays -- the law is never strip
     features. The bar takes a designed second row instead. */
  .top{flex-wrap:wrap;row-gap:8px;}
  .top-right{flex-wrap:wrap;justify-content:flex-end;row-gap:8px;}
  .pal{gap:6px;padding:4px 6px;}
  .pal button{width:13px;height:13px;}
  .mark{font-size:15px;letter-spacing:.05em;}
  .btn{padding:9px 12px;}
  .gate{padding-top:116px;}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto;}
  .k-dot,.invite .chev{animation:none;}
  .rise{opacity:1;transform:none;transition:none;}
  .cell,.cell img,.drop,.drop-img img{transition:none;}
  .cell:hover img{scale:1;}
}

/* --- the open invite: Add your world ------------------------------
   Same cell footprint as a real world so the invitation reads as a
   peer of the games, not an ad. Dashed border = an empty slot
   waiting to be filled; this is the flow Terraria actually arrived
   through, so the promise is real. */
.cell-add{border-style:dashed;border-width:2px;background:transparent;display:flex;align-items:center;justify-content:center;text-align:center;}
.cell-add::after{display:none;}
.cell-add:hover{border-color:var(--act);box-shadow:0 18px 48px -18px rgba(var(--act-rgb),.4);}
.cell-add-in{display:flex;flex-direction:column;align-items:center;gap:8px;padding:16px;min-width:0;}
.cell-add-plus{display:flex;align-items:center;justify-content:center;width:52px;height:52px;border-radius:50%;border:2px solid var(--act);color:var(--act);font-size:30px;line-height:1;font-family:var(--body);font-weight:500;transition:background .16s ease,color .16s ease,transform .16s ease;}
.cell-add:hover .cell-add-plus{background:var(--act);color:var(--act-ink);transform:scale(1.08);}
.cell-add .cell-name{white-space:normal;}
.cell-add .cell-meta{color:var(--dimmer);}

/* landing grid kill: site.css (loaded late for chat) carries the old
   blueprint-grid body::before; the landing declines it. */
body::before{content:none!important;}

/* the footer tagline - Brandon's line, verbatim */
.foot-tag{display:block;font-size:13px;color:var(--dimmer);letter-spacing:.01em;}

/* the what-it-does-for-you line, under the question */
.gate-what{display:block;font-size:clamp(14px,1.15vw,16.5px);color:var(--dim);max-width:54ch;line-height:1.6;margin:22px 0 0;}
@media (max-width:640px){.gate-what{font-size:13.5px;margin-top:18px;}}

/* The Signal broadcast mark - palette-reactive via currentColor */
.sig-link{display:inline-flex;align-items:center;}
.sig-link svg{width:25px;height:25px;color:var(--act);flex:0 0 auto;transition:color .2s ease,transform .15s ease;animation:sigHum 2.6s ease-in-out infinite;}
.sig-link:hover svg{color:var(--act-hi);transform:scale(1.12);}
@keyframes sigHum{0%,100%{opacity:.55;}50%{opacity:1;}}
@media (prefers-reduced-motion:reduce){.sig-link svg{animation:none;opacity:1;}}

/* --- THE GLOBE (2026-07-31): behind the gate's words --------------- */
/* The canvas paints in the palette's own --act/--live (read live from
   the root, re-read on every data-pal change), so this file only owns
   the layering and the vignette that keeps the headline legible. */
.gate{position:relative;}
.gate .ax-globe{opacity:.88;
  -webkit-mask-image:radial-gradient(circle at 50% 52%,#000 44%,rgba(0,0,0,.5) 70%,transparent 88%);
  mask-image:radial-gradient(circle at 50% 52%,#000 44%,rgba(0,0,0,.5) 70%,transparent 88%);}
.gate>*:not(.ax-globe){position:relative;z-index:1;}

/* --- top-bar corners eased on wide screens (2026-07-31) ------------ */
/* The bar stays full-bleed; its contents step in toward center — a
   little on a laptop, more on an ultrawide, never on mobile. */
@media(min-width:1100px){
  .top{padding-left:clamp(36px,6vw,120px);padding-right:clamp(36px,6vw,120px);}
}

/* --- top bar: avatar + world jump (2026-07-31) --------------------- */
/* overflow is VISIBLE, and the rounding moved onto the children. It was
   hidden so the parent could clip the photo into a circle -- which also
   clipped the unread badge pinned to its edge down to a sliver. The
   children round themselves now, so the circle is unchanged and anything
   sitting on the rim survives. position:relative is the badge's anchor. */
.top-ava{position:relative;display:inline-flex;width:34px;height:34px;border-radius:50%;overflow:visible;border:2px solid var(--act);box-shadow:0 0 10px rgba(var(--act-rgb),.45);flex:0 0 auto;}
.top-ava img{width:100%;height:100%;object-fit:cover;display:block;border-radius:50%;}
.top-ava-letter{width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:var(--panel-2);color:var(--act);font-family:var(--display);font-weight:800;font-size:15px;border-radius:50%;}
.top-worlds{appearance:none;-webkit-appearance:none;background:var(--panel) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6" viewBox="0 0 10 6"><path d="M1 1l4 4 4-4" fill="none" stroke="%23a09db4" stroke-width="1.6" stroke-linecap="round"/></svg>') no-repeat right 10px center;border:1px solid var(--line);border-radius:9px;color:var(--text);font-family:var(--mono);font-size:12px;letter-spacing:.04em;padding:8px 28px 8px 12px;cursor:pointer;}
.top-worlds:focus{outline:none;border-color:var(--act);}

/* --- app-feel: no default anything (2026-07-31) -------------------- */
@supports not selector(::-webkit-scrollbar){*{scrollbar-width:thin;scrollbar-color:rgba(var(--act-rgb),.6) rgba(255,255,255,.06);}}
::-webkit-scrollbar{width:10px;height:10px;}
::-webkit-scrollbar-track{background:rgba(255,255,255,.03);}
::-webkit-scrollbar-thumb{background:var(--act);border-radius:8px;border:2px solid var(--void);}
::-webkit-scrollbar-thumb:hover{background:var(--act-hi);}
::selection{background:rgba(var(--act-rgb),.38);color:#fff;}

/* --- TAPPED IN RIGHT NOW (2026-07-31) ------------------------------ */
.gate-live{display:inline-flex;align-items:center;gap:8px;margin-top:18px;font-family:var(--mono);font-size:11.5px;letter-spacing:.22em;text-transform:uppercase;color:var(--dim);}
.gate-live i{width:7px;height:7px;border-radius:50%;background:var(--live);box-shadow:0 0 10px var(--live);animation:gateLivePulse 2.6s ease-in-out infinite;}
@keyframes gateLivePulse{0%,100%{opacity:1;}50%{opacity:.45;}}
@media(prefers-reduced-motion:reduce){.gate-live i{animation:none;}}

/* --- the real switcher, landing edition (2026-07-31) --------------- */
/* Same anatomy as site.css's component, tokens mapped to this file's. */
.game-switcher{position:relative;}
.game-switcher-trigger{display:flex;align-items:center;gap:6px;background:none;border:1px solid var(--line);color:var(--dim);padding:7px 10px;border-radius:6px;font-family:var(--body);font-size:.82rem;cursor:pointer;white-space:nowrap;min-width:0;}
.game-switcher-trigger span{overflow:hidden;text-overflow:ellipsis;}
.game-switcher-trigger .gsw-short{display:none;}
.game-switcher-trigger:hover{border-color:var(--act);color:var(--text);}
.game-switcher-panel{position:absolute;top:calc(100% + 6px);right:0;width:230px;z-index:60;background:var(--panel-2);border:1px solid var(--line);border-radius:8px;box-shadow:0 16px 40px rgba(0,0,0,.55);padding:8px;}
.game-switcher-search{width:100%;padding:8px 10px;margin-bottom:6px;background:rgba(5,7,13,.6);border:1px solid var(--line);color:var(--text);border-radius:6px;font-family:var(--body);font-size:.85rem;box-sizing:border-box;}
.game-switcher-search:focus{outline:none;border-color:var(--act);}
.game-switcher-list{list-style:none;margin:0;padding:0;max-height:240px;overflow-y:auto;}
.game-switcher-list li[hidden]{display:none;}
.game-switcher-list a{display:block;padding:8px 10px;border-radius:6px;color:var(--dim);text-decoration:none;font-size:.88rem;}
.game-switcher-list a:hover{background:rgba(var(--act-rgb),.14);color:var(--text);}
.game-switcher-empty{padding:10px;color:var(--dimmer);font-family:var(--mono);font-size:.72rem;text-align:center;}
.top-login{display:inline-flex;align-items:center;color:var(--dim);transition:color .16s ease;}
.top-login:hover{color:var(--text);}

/* ============================================================
   WHERE ARE YOU TAPPING IN FROM? - the deep-zoom planet v2.
   Day/night toggle, on-map search, pin color swatches, PULSE
   accent copy. Leaflet-driven, same engine as the field maps.
   ============================================================ */
.zt-accent{color:var(--ion);}
.zt-pulse{color:var(--ion);font-weight:800;letter-spacing:.06em;}
.tapmap{position:relative;border:1px solid var(--line);border-radius:14px;overflow:hidden;background:#000;box-shadow:0 20px 60px -30px rgba(0,0,0,.9);}
#tapmapCanvas{height:min(74vh,720px);background:#000;cursor:crosshair;}
#tapmapCanvas .leaflet-container{background:#000;}
.tapmap .leaflet-bar a{background:var(--panel)!important;color:var(--text)!important;border-color:var(--line)!important;}
.tapmap .leaflet-bar a:hover{background:var(--panel-2)!important;color:var(--ion)!important;}
.tapmap .leaflet-tooltip{background:var(--panel);border:1px solid var(--line);color:var(--text);font-family:var(--mono);font-size:11px;letter-spacing:.04em;border-radius:7px;box-shadow:0 8px 24px -10px rgba(0,0,0,.8);}
.tapmap-seek{position:absolute;top:12px;left:56px;z-index:1200;width:min(340px,calc(100% - 190px));}
.tapmap-seek input{width:100%;background:rgba(5,7,13,.88);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);border:1px solid var(--line);border-radius:10px;padding:10px 13px;color:var(--text);font-family:var(--body);font-size:13.5px;box-sizing:border-box;}
.tapmap-seek input:focus{outline:2px solid rgba(var(--ion-rgb),.45);border-color:var(--ion);}
.tapmap-results{position:absolute;top:calc(100% + 6px);left:0;width:100%;background:rgba(5,7,13,.96);border:1px solid var(--line);border-radius:10px;overflow:hidden;box-shadow:0 18px 50px -20px rgba(0,0,0,.9);}
.tapmap-results button{display:block;width:100%;text-align:left;background:none;border:none;border-bottom:1px solid var(--line-soft);padding:10px 13px;color:var(--text);font-family:var(--mono);font-size:11.5px;letter-spacing:.03em;cursor:pointer;}
.tapmap-results button:last-child{border-bottom:none;}
.tapmap-results button:hover{background:rgba(var(--ion-rgb),.14);color:var(--star);}
.tapmap-mode{position:absolute;top:12px;right:12px;z-index:1200;display:inline-flex;gap:5px;background:rgba(5,7,13,.88);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);border:1px solid var(--line);border-radius:10px;padding:4px;}
.tapmap-mode button{background:none;border:none;border-radius:7px;padding:6px 12px;color:var(--text-dim);font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;cursor:pointer;}
.tapmap-mode button:hover{color:var(--text);}
.tapmap-mode button.on{background:rgba(var(--ion-rgb),.18);color:var(--star);}
/* display:none is the DEFAULT and .on is the only thing that shows it.
   This element used to carry display:flex with an [hidden] attribute for
   state, and an author display rule beats the UA [hidden] rule -- so
   "hidden" left a bordered empty box on the map. Every rule that makes it
   visible now carries one more class than the rule it overrides, in this
   file AND in the phone media query below, so neither can be undone by
   source order. */
.tapmap-hint{position:absolute;left:50%;bottom:16px;transform:translateX(-50%);background:rgba(5,7,13,.94);border:1px solid var(--ion);border-radius:10px;padding:10px 16px;font-family:var(--mono);font-size:11.5px;letter-spacing:.05em;color:var(--text);white-space:nowrap;z-index:1200;display:none;align-items:center;gap:10px;max-width:92%;}
.tapmap-hint.on{display:flex;}
.tapmap-hint a{color:var(--star);text-decoration:none;}
.tapmap-hint button{background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:6px 12px;color:var(--text);font-family:var(--mono);font-size:11px;letter-spacing:.05em;cursor:pointer;}
.tapmap-hint button:hover{border-color:var(--ion);color:var(--star);}
.tapmap-hint #tapmapMoveYes{border-color:var(--ion);color:var(--star);}
.tapmap-bridge{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:14px;color:var(--text-dim);font-size:14px;}
.tapmap-bridge select{background:var(--panel);border:1px solid var(--line);border-radius:9px;padding:9px 12px;color:var(--text);font-family:var(--mono);font-size:12px;letter-spacing:.04em;cursor:pointer;}
.tapmap-bridge select:hover{border-color:var(--ion);}
.tapmap-pincolors{display:inline-flex;align-items:center;gap:7px;padding:7px 11px;border:1px solid var(--line);border-radius:10px;background:var(--panel);}
.tpc-label{font-family:var(--mono);font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:var(--text-dimmer);margin-right:2px;}
.tpc-swatch{width:16px;height:16px;border-radius:50%;border:1.5px solid rgba(255,255,255,.25);background:var(--sw);cursor:pointer;padding:0;transition:transform .12s ease,border-color .12s ease;}
.tpc-swatch:hover{transform:scale(1.2);}
.tpc-swatch.on{border-color:#fff;box-shadow:0 0 0 2px rgba(var(--ion-rgb),.5);transform:scale(1.15);}
@media (max-width:640px){#tapmapCanvas{height:62vh;}.tapmap-seek{left:12px;width:calc(100% - 150px);}.tapmap-bridge{font-size:13px;}.tapmap-hint{white-space:normal;}}

/* ---- blips: live board, arrivals, and the in-place editor ---- */
.tapin-blip{transition:opacity .2s ease;}
.tapin-blip-new{animation:blip-arrive 1.8s ease-out 2;transform-origin:center;transform-box:fill-box;}
@keyframes blip-arrive{0%{opacity:.25;}45%{opacity:1;}100%{opacity:.9;}}
.tapin-blip-mine{cursor:pointer;}
.blip-tip{max-width:260px;white-space:normal;text-align:left;}
.blip-tip b{display:block;color:var(--star);font-family:var(--mono);font-size:11px;letter-spacing:.05em;}
.blip-tip .blip-msg{display:block;margin-top:4px;color:var(--text);font-family:var(--body);font-size:12.5px;line-height:1.4;}
.blip-tip .blip-hint{display:block;margin-top:5px;color:var(--text-dimmer);font-family:var(--mono);font-size:9.5px;letter-spacing:.09em;text-transform:uppercase;}
.blip-popup .leaflet-popup-content-wrapper{background:rgba(5,7,13,.97);border:1px solid var(--ion);border-radius:12px;box-shadow:0 18px 50px -18px rgba(0,0,0,.95);}
.blip-popup .leaflet-popup-tip{background:rgba(5,7,13,.97);border:1px solid var(--ion);}
.blip-popup .leaflet-popup-content{margin:14px 16px;width:auto!important;}
.blip-pop{min-width:238px;}
.bp-title{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--text-dimmer);margin-bottom:9px;}
.bp-colors{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:12px;}
.bp-sw{width:17px;height:17px;border-radius:50%;border:1.5px solid rgba(255,255,255,.28);background:var(--sw);cursor:pointer;padding:0;transition:transform .12s ease;}
.bp-sw:hover{transform:scale(1.18);}
.bp-sw.on{border-color:#fff;box-shadow:0 0 0 2px rgba(var(--ion-rgb),.55);transform:scale(1.12);}
.bp-state{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-dimmer);margin-bottom:4px;}
.bp-live,.bp-pending{color:var(--text);font-size:13px;line-height:1.45;margin-bottom:8px;}
.bp-pending{color:var(--star);font-style:italic;}
.bp-link{background:none;border:none;padding:0;margin-right:12px;color:var(--star);font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;cursor:pointer;}
.bp-link:hover{text-decoration:underline;}
.bp-link.bp-danger{color:#ff9baa;}
.bp-form{margin-top:9px;}
.bp-form input{width:100%;background:rgba(255,255,255,.04);border:1px solid var(--line);border-radius:8px;padding:9px 11px;color:var(--text);font-family:var(--body);font-size:13px;box-sizing:border-box;margin-bottom:8px;}
.bp-form input:focus{outline:2px solid rgba(var(--ion-rgb),.4);border-color:var(--ion);}
.bp-form button{background:rgba(var(--ion-rgb),.18);border:1px solid var(--ion);border-radius:8px;padding:7px 14px;color:var(--star);font-family:var(--mono);font-size:11px;letter-spacing:.06em;cursor:pointer;}
.bp-form button:hover{background:rgba(var(--ion-rgb),.3);color:#fff;}
.bp-note{margin-top:8px;color:var(--text-dimmer);font-family:var(--mono);font-size:9.5px;letter-spacing:.04em;line-height:1.5;}
.bp-err{margin-top:9px;color:#ff9baa;font-family:var(--mono);font-size:10.5px;line-height:1.45;}
.tapmap-count{position:absolute;left:14px;bottom:14px;z-index:1150;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--text-dim);background:rgba(5,7,13,.8);border:1px solid var(--line);border-radius:8px;padding:6px 11px;pointer-events:none;}
@media (prefers-reduced-motion:reduce){.tapin-blip-new{animation:none;}}

/* ---- v3: pulse broadcast, look-around hint, field-map jump ---- */
.tapin-blip-pulsing{animation:blip-broadcast 1.5s ease-in-out infinite;transform-origin:center;transform-box:fill-box;}
@keyframes blip-broadcast{0%,100%{opacity:1;stroke-width:2;}50%{opacity:.45;stroke-width:9;}}
.tapmap-hint .hint-place{color:var(--star);font-weight:700;letter-spacing:.04em;}
.tapmap-hint .hint-sub{color:var(--text-dim);}
.bp-pulse{display:block;width:100%;margin-top:12px;background:rgba(var(--ion-rgb),.16);border:1px solid var(--ion);border-radius:8px;padding:9px 12px;color:var(--star);font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;transition:background .15s ease,color .15s ease;}
.bp-pulse:hover{background:rgba(var(--ion-rgb),.32);color:#fff;}
.tapmap-bridge{align-items:flex-start;}
.tmb-lead{flex:1 1 340px;min-width:0;color:var(--text-dim);font-size:14px;line-height:1.6;}
.tapmap-jump{position:relative;flex:0 0 auto;}
.tmj-trigger{display:inline-flex;align-items:center;gap:9px;background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:10px 14px;color:var(--text);font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;cursor:pointer;transition:border-color .15s ease,color .15s ease;}
.tmj-trigger:hover{border-color:var(--ion);color:var(--star);}
.tmj-trigger svg{width:14px;height:14px;flex:0 0 auto;}
.tmj-list{position:absolute;right:0;bottom:calc(100% + 8px);min-width:240px;margin:0;padding:6px;list-style:none;background:var(--panel);border:1px solid var(--line);border-radius:11px;box-shadow:0 20px 54px -18px rgba(0,0,0,.92);z-index:80;max-height:320px;overflow-y:auto;}
.tmj-list li{list-style:none;}
.tmj-list a{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 11px;border-radius:8px;color:var(--text);text-decoration:none;font-size:13px;}
.tmj-list a:hover{background:rgba(var(--ion-rgb),.14);color:var(--star);}
.tmj-list em{font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--text-dimmer);font-style:normal;}
@media (max-width:640px){.tmj-list{left:0;right:auto;min-width:0;width:100%;}}

/* ---- the planet on a phone (2026-08-01, from Brandon's screenshot):
   the search box sat ON TOP of Leaflet's zoom buttons, the hover card
   ran off the right edge, and the hint box's flex row squeezed the
   place name into a 3-character column. All three fixed by giving the
   phone its own layout instead of shrinking the desktop one. ---- */
@media (max-width: 700px) {
  /* Search leaves the overlay and becomes a real strip above the map,
     which hands the top-left corner back to the zoom controls. */
  .tapmap-seek { position: static; width: auto; padding: 10px 10px 0; }
  .tapmap-seek input { font-size: 16px; }   /* 16px = iOS will not zoom the page on focus */
  .tapmap-results { left: 10px; width: calc(100% - 20px); top: calc(100% - 2px); }
  .tapmap-mode { top: auto; bottom: 12px; right: 10px; }
  #tapmapCanvas { height: 58vh; min-height: 320px; }
  /* The hint box was display:flex with a gap, so the place name became
     its own narrow flex column ("Yoyogi / . JP" stacked). Block layout
     lets the sentence read as a sentence. */
  .tapmap-hint.on { display: block; }
  .tapmap-hint {
    white-space: normal; text-align: center;
    left: 10px; right: 10px; transform: none; max-width: none;
    bottom: 62px; line-height: 1.55; padding: 10px 12px;
  }
  .tapmap-hint .hint-place { display: inline; }
  .tapmap-hint button { margin: 6px 4px 0; }
  /* Tooltips were escaping the right edge; keep them inside the card. */
  .tapmap .leaflet-tooltip { max-width: 62vw; white-space: normal; }
  /* The popup gets a DEFINITE width on a phone. It used to get
     min-width:0, which hands it to shrink-to-fit -- and shrink-to-fit
     on a column of short words collapses into a ~100px ribbon reading
     two words per line, which is what Brandon photographed on
     2026-08-01. There was never a fit problem to solve: measured the
     same night, the map is 344px wide inside a 390px phone, so 238px
     of popup always had room. A definite width also makes the popup
     SHORTER, which is what stops it overflowing the top of a 487px
     map and getting clipped. */
  .blip-popup .leaflet-popup-content { margin: 12px 13px; width: min(276px, 74vw) !important; }
  .blip-pop { min-width: 0; } /* moot now the width above is definite */
  .tapmap-bridge { flex-direction: column; align-items: stretch; }
  .tapmap-jump, .tmj-trigger { width: 100%; justify-content: space-between; }
}

/* ---- v4 (Brandon's pass): readout at the TOP, PULSE is a button,
   the jump strip reads as one thing ---- */
.tapmap-hint { top: 64px; bottom: auto; }
button.zt-pulse { background: none; border: none; padding: 0 1px; margin: 0; font: inherit; font-weight: 800; letter-spacing: .06em; color: var(--ion); cursor: pointer; position: relative; }
button.zt-pulse::after { content: ''; position: absolute; left: 0; right: 0; bottom: -2px; height: 1px; background: currentColor; opacity: .35; transition: opacity .18s ease; }
button.zt-pulse:hover { color: var(--star); }
button.zt-pulse:hover::after { opacity: 1; }
button.zt-pulse.firing { animation: pulse-word 1.4s ease-in-out infinite; }
@keyframes pulse-word { 0%, 100% { opacity: 1; text-shadow: 0 0 6px rgba(var(--ion-rgb), .7); } 50% { opacity: .55; text-shadow: 0 0 16px rgba(var(--ion-rgb), 1); } }
/* One strip, not a sentence with a stray control beside it. */
.tapmap-bridge { align-items: center; gap: 16px; margin-top: 16px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); }
.tmb-lead { flex: 1 1 300px; color: var(--text-dim); font-size: 13.5px; line-height: 1.6; }
.tmj-list { min-width: 200px; }
.tmj-list a { justify-content: flex-start; }
@media (max-width: 700px) {
  .tapmap-hint { top: 66px; }
  .tapmap-bridge { flex-direction: column; align-items: stretch; gap: 12px; padding: 13px 14px; }
  .tmb-lead { flex: none; }
}
@media (prefers-reduced-motion: reduce) { button.zt-pulse.firing { animation: none; } }

/* ---- v5: the lead and its control travel together ----
   flex:1 1 300px let the sentence grow to fill the strip, which shoved
   the button to the far right and made the pair read as two unrelated
   things. They belong side by side; the strip is left-aligned and the
   sentence takes only the width it needs. */
.tapmap-bridge { justify-content: flex-start; gap: 12px; flex-wrap: wrap; }
.tmb-lead { flex: 0 1 auto; }
.tapmap-hint .hint-pulse { color: var(--ion); font-weight: 800; letter-spacing: .06em; }
@media (max-width: 700px) {
  .tapmap-bridge { gap: 10px; }
}

/* ---- the header must outrank the map (Brandon, 2026-08-01: the
   game-switcher panel was being painted over by the planet) ----
   header is position:fixed with z-index:100, which makes it a stacking
   context -- everything inside it, including the switcher panel's own
   z-index:500, is trapped at level 100. Leaflet meanwhile uses 400 for
   panes, 800 for controls and 1000 for its corner containers, and my
   own overlays sat at 1200, so the whole map painted above the header
   and swallowed any panel hanging below it.
   The fix is NOT to raise the header (that would put it above modals
   too). It is to give the map its own low stacking context, so every
   Leaflet layer and overlay inside it composites at level 1 on the
   page. field-map.php has always done exactly this on #palmap -- which
   is why the game maps never had this bug. The landing map simply
   never got the same line. */
.tapmap { z-index: 1; }

/* ---- the ninja edit inside your own blip ---- */
.bp-move { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line-soft); position: relative; }
.bp-move label { display: block; font-family: var(--mono); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-dimmer); margin-bottom: 5px; }
.bp-move input { width: 100%; background: rgba(255,255,255,.04); border: 1px solid var(--line); border-radius: 8px; padding: 9px 11px; color: var(--text); font-family: var(--body); font-size: 13px; box-sizing: border-box; }
.bp-move input:focus { outline: 2px solid rgba(var(--ion-rgb),.4); border-color: var(--ion); }
.bp-move-results { position: absolute; left: 0; right: 0; top: calc(100% - 34px); z-index: 5; max-height: 190px; overflow-y: auto; background: rgba(5,7,13,.98); border: 1px solid var(--ion); border-radius: 9px; box-shadow: 0 16px 44px -14px rgba(0,0,0,.95); }
.bp-move-results button { display: block; width: 100%; text-align: left; background: none; border: none; border-bottom: 1px solid var(--line-soft); padding: 9px 11px; color: var(--text); font-family: var(--mono); font-size: 11px; letter-spacing: .02em; cursor: pointer; }
.bp-move-results button:last-child { border-bottom: none; }
.bp-move-results button:hover { background: rgba(var(--ion-rgb),.16); color: var(--star); }

/* ---- v7: the box hugs what is in it ----
   The strip was a full-width bordered panel holding about 780px of
   content, so on a 1790px map there was a thousand pixels of nothing
   inside the border -- the emptiness read as a mistake rather than as
   space. Left-aligning the content (v5, above) fixed the sentence and
   its button drifting apart but could not fix that, because the PANEL
   was still stretching.

   fit-content collapses the border onto the pair, which puts "Jump to a
   Game" at the right-hand end of the box with nothing after it, and
   centres the whole thing under the map as a caption rather than a bar.
   Above the 700px breakpoint only: below it the strip deliberately
   becomes a full-width stacked column, and shrink-to-fit would fight
   that. */
@media (min-width: 701px) {
  .tapmap-bridge { width: fit-content; max-width: 100%; margin-left: auto; margin-right: auto; }
}
