@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');

/* =====================================================================
   PRIME — the inner-page bridge.               (pilot: tappedin.gg)

   Three palettes, chosen on the landing, carried here by the tapin_pal
   cookie (header-full stamps data-pal before paint):

     VOLTAGE (default)  act #8a2bff / live #00f0ff
     SOLAR              act #ff5400 / live #ffc400
     ACID               act #23f26b / live #c8ff2e

   --ion is the token every inner component references: it maps to the
   palette's ACT colour; --ember maps to LIVE. The extra --act-ink token
   keeps button text readable per palette (white on violet, near-black
   on orange and green).

   THE AMBIENT v4: gated to real game-content pages only — a page that
   has no world (register, the hub) or is not a content
   page never shows it, so neutral ground stays neutral. Its crop now
   comes from the game's own focal sidecar, emitted inline server-side,
   so no half-cropped logo lettering.
   ===================================================================== */

:root:root{
  --void:#0a0a10;
  --panel:#12121b;
  --panel-2:#191926;
  --line:#262638;
  --line-soft:#191926;

  --ion:#8a2bff;
  --ion-rgb:138,43,255;
  --ion-dim:#6c1fd6;
  --star:#a866ff;
  --ember:#00f0ff;
  --act-ink:#ffffff;

  --text:#f4f3fb;
  --text-dim:#a09db4;
  --text-dimmer:#62607c;

  --display:'Big Shoulders',sans-serif;
  --body:'Onest',sans-serif;
  --mono:'Spline Sans Mono',monospace;
}
:root:root[data-pal="solar"]{
  --ion:#ff5400;--ion-rgb:255,84,0;--ion-dim:#d64500;--star:#ff7a33;--ember:#ffc400;--act-ink:#180700;
}
:root:root[data-pal="acid"]{
  --ion:#23f26b;--ion-rgb:35,242,107;--ion-dim:#12c452;--star:#5cff93;--ember:#c8ff2e;--act-ink:#001408;
}

#stars{display:none!important;}
body::before{opacity:.04!important;}
html,body{overflow-x:clip;}

/* --- THE AMBIENT v4 -------------------------------------------------- */
/* Position arrives inline from the game's own focal sidecar. */
.game-ambient{position:fixed;top:0;left:0;right:0;height:60vh;z-index:0;pointer-events:none;
  background-size:cover;
  /* opacity now arrives inline, per world, from that game's own row --
     see axiom_game_ambient_opacity(). A value here would be a second
     definition of the same thing and would win or lose by accident. */
  filter:saturate(1.12);
  -webkit-mask-image:radial-gradient(ellipse 135% 120% at 60% -10%,black 16%,rgba(0,0,0,.5) 54%,transparent 82%);
  mask-image:radial-gradient(ellipse 135% 120% at 60% -10%,black 16%,rgba(0,0,0,.5) 54%,transparent 82%);}

/* MEMBER ROOMS WEAR A GENTLER FADE. The radial mask above is tuned for a
   WORLD's art -- atmospheric, subordinate, half-strength by mid-band. On a
   member's own wall it was eating the picture (measured 2026-08-20 on the
   live wall: .58 at the avatar line, .49 mid-band, .32 on the left where
   the art's detail lived, 0 before the band's bottom edge). Ruled
   2026-08-20: TAP provides the foundation, the member owns the decorating.
   So member art keeps its clarity everywhere and fades ONLY at the bottom
   seam, where the fixed band hands off into the page. Blur-fill and the
   member's own strength slider are untouched -- this only stops the
   platform dimming the picture. One extra class so this wins by
   specificity, never by source order. */
.game-ambient.room-wall{
  -webkit-mask-image:linear-gradient(to bottom,black 70%,transparent 100%);
  mask-image:linear-gradient(to bottom,black 70%,transparent 100%);}

/* The rule that stood here hid JOIN GAME outright, saying the switcher
   carried the function. It did not: the switcher moves you between worlds
   and has never been able to follow one, and account.php can only manage
   games you already follow. So from 2026-07-31 to 2026-08-08 there was no
   way for a member to join a world, and nothing failed or logged.
   Removed with the markup it hid, so the trap cannot re-arm on a future
   element that happens to carry .world-join-btn. The way in is now
   includes/game-follow.php, on the world's own name line.
   Nothing hides to make a layout fit. */

/* --- header ---------------------------------------------------------- */
header{background:rgba(10,10,16,.84)!important;border-bottom:1px solid var(--line-soft);}
.brand{font-family:var(--display);font-weight:800;font-size:16px;letter-spacing:.07em;text-transform:uppercase;text-shadow:none;color:var(--text);gap:9px;align-items:center;}
.tapin-mark{display:inline-block;width:11px;height:11px;border-radius:3px;background:linear-gradient(135deg,var(--ember) 0%,var(--ion) 52%,var(--ion-dim) 100%);box-shadow:0 0 12px rgba(var(--ion-rgb),.7);flex-shrink:0;}

.nav-links{gap:24px;font-size:14px;font-weight:500;}
/* THE LINKS WEAR THE VISITOR'S PALETTE (Brandon, 2026-08-21: "our unique
   gift to our visitors -- lets them pick a color, not just be stuck with
   our brand color"). --star is each palette's bright accent and follows
   data-pal automatically; mixed toward the dim text at rest so seven
   links read as navigation, not neon -- full accent on hover, full text
   on the page you are standing on. */
.nav-links a{position:relative;padding:5px 0;color:color-mix(in srgb, var(--star) 58%, var(--text-dim));transition:color .16s ease;}
.nav-links a:hover{color:var(--star);}
.nav-links a.active-link{color:var(--text);}
.nav-links a.active-link::after{content:'';position:absolute;left:0;right:0;bottom:-1px;height:2px;border-radius:2px;background:linear-gradient(90deg,var(--ion),var(--ember));}

.btn-join{border-radius:11px!important;font-family:var(--body);font-weight:700;background:var(--ion);color:var(--act-ink);letter-spacing:.06em;text-transform:uppercase;transition:background .16s ease,transform .1s ease;}
.btn-join:hover{background:var(--star);}
.btn-join:active{transform:translateY(1px);}
.btn,button.btn,a.btn{border-radius:11px!important;font-family:var(--body);font-weight:600;letter-spacing:0;}
.btn-primary{background:var(--ion);color:var(--act-ink);border:1px solid var(--ion);}
.btn-primary:hover{background:var(--star);border-color:var(--star);}

/* --- surfaces --------------------------------------------------------- */
/* RETIRED 2026-09-08 — .game-card,.hub-card,.world-card. All THREE
   selectors were unproduced across the living tree: no markup emitted any
   of them, and on the hub, a world page and the catalogue hub they matched
   zero nodes. The hub's tiles wear .cell; the catalogue's cards wear
   .cat-hub-card, which is a different class token this rule never matched. */

/* selection/scrollbar/focus rules REMOVED 2026-08-01 — an older
   duplicate of the app-feel cluster. THE UNIFORMITY LAW: that lives in
   site.css only. A theme file recolors; it never carries base
   experience. */
.accent{color:var(--ember);}

.section-eyebrow,.eyebrow,.crumbs,.breadcrumbs{font-family:var(--mono);letter-spacing:.14em;text-transform:uppercase;font-size:10.5px;}

.page-head,.catalogue-head,.section-head{padding-top:18px!important;}
.page-head h1,.catalogue-head h1{font-size:clamp(28px,3.6vw,44px)!important;margin-bottom:8px!important;letter-spacing:.03em;text-transform:uppercase;}
h1,h2,h3,h4,.section-head h2{letter-spacing:.02em;}

/* --- the hamburger is a signpost, not furniture --------------------
   It takes the palette's action colour so a first-time visitor on
   mobile knows exactly where navigation lives, and it re-tints the
   moment the palette switches. */
.menu-toggle{color:var(--ion)!important;border:2px solid var(--ion)!important;border-radius:10px!important;box-shadow:0 0 16px rgba(var(--ion-rgb),.35);transition:background .16s ease,color .16s ease,box-shadow .2s ease;}
.menu-toggle:hover,.menu-toggle:focus-visible{background:var(--ion);color:var(--act-ink)!important;box-shadow:0 0 22px rgba(var(--ion-rgb),.55);}

/* --- the palette switcher, now sitewide ---------------------------- */
.pal{display:flex;align-items:center;gap:9px;padding:6px 9px;border:1px solid var(--line);border-radius:11px;}
.pal button{display:block;width:14px;height:14px;border-radius:50%;border:2px solid transparent;padding:0;cursor:pointer;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);}
@media (max-width:520px){.pal{padding:5px 7px;gap:7px;}.pal button{width:12px;height:12px;}}

/* --- chat pops in the palette --------------------------------------
   The widget is token-driven already (66 var(--ion) references), so
   it follows the palette by construction; these lines make the
   launcher legible per palette and give it the brand glow. */
.ax-chat-launcher{color:var(--act-ink)!important;}
.ax-chat{box-shadow:0 8px 34px -12px rgba(var(--ion-rgb),.55);}
/* NO PALETTE TOUCHES THE UNREAD BADGE. It was set from --ember here,
   which every palette redefines, so the one alert colour in the UI moved
   with the theme. It is pinned on :root in site.css now, deliberately
   outside every palette's reach. */

/* The Signal broadcast mark (footer) - palette-reactive */
.signal-link svg{width:15px;height:15px;color:var(--ion);flex:0 0 auto;transition:color .2s ease;}
.signal-link:hover svg{color:var(--star);}

/* --- guest chat bubble: styles moved INTO includes/chat-widget.php
   (2026-07-31). It must render on pages that load no site chrome at
   all (the guest landing loads only proto-p9.css), so its styles now
   travel with its markup, scoped under #chatTeamRoot. One source. */
/* launcher follows the palette wherever the old css hardcoded */
.ax-chat-launcher{background:var(--ion)!important;color:var(--act-ink)!important;}

/* --- header truly centered (2026-07-31) ---------------------------- */
/* The wrap was flex space-between: the middle links centered in the
   LEFTOVER space, and the right cluster (~292px) far outweighs the
   brand (~65px), so the nav sat a measured ~115px left of the page's
   true centerline. A 3-column grid centers the middle column on the
   wrap itself, which is centered on the viewport. */
header nav.wrap{display:grid;grid-template-columns:1fr max-content 1fr;align-items:center;column-gap:18px;max-width:1072px;padding-left:20px!important;padding-right:20px!important;}
/* Children PINNED to their columns: .nav-links is display:none on
   mobile, and a hidden grid child generates no box — without explicit
   placement the right cluster auto-flowed into the middle column and
   the whole bar read pushed-left (measured live on a 386px viewport,
   2026-07-31). */
header nav.wrap .brand{grid-column:1;justify-self:start;}
header nav.wrap .nav-links{grid-column:2;justify-self:center;margin-left:0;}
header nav.wrap .nav-cta{grid-column:3;justify-self:end;margin-left:0;}

/* THE NAV SPREAD (iron three, 2026-08-20; Brandon's direction). The centered
   grid above was right for the narrow, centered site PRIME shipped on — the
   premise moved: the room is wide now and the upper-right corner belongs to
   the page (the profile's social group lives there). On rooms wide enough
   the header spans instead: wordmark and links seated left, the widget
   cluster seated right, 40px off each edge to match the page shells. Same
   grid, re-weighted — the 1fr spacer moves to the middle. Below 1200px the
   centered composition above still stands. */
/* AMENDED 2026-08-21 (Brandon): the LINKS return to true center at every
   width -- "Center the links/nav. not the TAPPED IN nor the color picker."
   The spread's other half stands: wordmark seated at the left edge, the
   widget cluster at the right, 40px off each edge. Equal 1fr flanks on a
   full-width wrap put the middle column on the viewport's centerline
   regardless of the two sides' unequal weight. */
@media (min-width:1200px){
  header nav.wrap{grid-template-columns:1fr max-content 1fr;max-width:none;column-gap:26px;padding-left:40px!important;padding-right:40px!important;}
}

/* --- THE SIGNAL GOLD STANDS ON ITS OWN (2026-08-11) --------------- */
/* What stood here remapped the three --sig-gold custom properties to the
   palette at :root. It is REMOVED, and this is not the correction of a
   mistake.

   THE ORIGINAL DECISION WAS RIGHT; ITS MECHANISM WAS TOO WIDE. The comment
   said 'the Signal unread badge' -- singular -- but the remap sat on :root, so it
   also caught the image focus picker's dot, slider and flag checkbox, the
   leveled-multiselect boost badge, my-submissions' recenter nudge, and every
   piece of My Signal's own chrome. Those are INSTRUMENTS, and an affordance
   that changes colour per person cannot teach anyone anything.

   AND ITS PREMISE MOVED. 'Follow the palette' was coherent when the palette
   was one fixed brand identity. PRIME skins made --ion per-person (see the
   skin blocks above) and the aurora made the room per-person and daily. A
   decision whose premise moved is not a bug -- it is a decision to re-make.

   THE LINE IT WAS SETTLED ON (Brandon, 2026-08-11): the room colour is the
   worlds you follow, the accent colour is the person, and gold is the only
   thing that is neither -- which is exactly what makes it the instrument
   panel. If the Signal's identity is ALSO the personal accent, the climate
   and the chrome fight each other.

   NOTHING IS LOST MECHANICALLY. site.css's pulse keyframes read
   var(--sig-gold-rgb) rather than a literal, so the badge's drop-shadows
   still follow the token -- they now follow it to #ffc65c. Base values live
   in assets/site.css:94. */
/* (the remap that stood here is gone -- see above) */

/* app-feel block MOVED to site.css 2026-08-01 — THE UNIFORMITY LAW:
   base-experience rules live in the base stylesheet every page loads,
   never in a theme layer. */

/* --- boards, room to breathe (2026-07-31) -------------------------- */
.cat-row{padding:18px 20px!important;gap:16px!important;margin-bottom:12px!important;}
.cat-name{font-size:1.04rem!important;}
.cat-desc{font-size:.86rem!important;line-height:1.55!important;margin-top:3px!important;}
.cat-stats{font-size:.78rem!important;white-space:nowrap!important;}

/* --- switcher: favorites starred, All Games pinned (2026-07-31) ---- */
.signal-chip-fav{color:var(--ember);font-size:.72em;vertical-align:1px;margin-left:3px;}
.world-switcher-list .world-switcher-all{border-bottom:1px solid var(--line);margin-bottom:4px;padding-bottom:4px;}
.world-switcher-list .world-switcher-all a{font-family:var(--mono);font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;color:var(--star);}

/* --- the invitation rule (2026-07-31): every submit surface asks --- */
.submit-invite{display:block;margin-top:8px;font-size:12.5px;line-height:1.55;color:var(--text-dim);}

/* --- Signal unread badge (2026-07-31): the pulse carries a number -- */
.signal-count{position:absolute;top:0;right:-6px;min-width:16px;height:16px;padding:0 4px;border-radius:8px;background:var(--ember);color:#0a0a10;font-family:var(--mono);font-size:.6rem;font-weight:700;display:inline-flex;align-items:center;justify-content:center;line-height:1;box-shadow:0 0 8px rgba(var(--ion-rgb),.45);z-index:2;}

/* --- member chat, PRIME energy (2026-07-31) ------------------------ */
.ax-chat.open{border-color:var(--ion);box-shadow:0 20px 56px rgba(0,0,0,.6),0 0 34px rgba(var(--ion-rgb),.16);}
.ax-chat-head{background:rgba(var(--ion-rgb),.07);}
.ax-chat-title{font-family:var(--display);font-size:.92rem;letter-spacing:.06em;color:var(--text);}
.ax-chat-row{border:1px solid transparent;transition:background .14s ease,border-color .14s ease;}
.ax-chat-row:hover{background:rgba(var(--ion-rgb),.12);border-color:rgba(var(--ion-rgb),.35);}
.ax-chat-row-unread{box-shadow:0 0 8px color-mix(in srgb, var(--ax-unread) 42%, transparent);}
.ax-chat-msg.mine{background:rgba(var(--ion-rgb),.16);border-color:var(--ion-dim);}
.ax-chat-empty{font-family:var(--mono);letter-spacing:.04em;}
.ax-chat-more{color:var(--star);}
.ax-chat-more:hover{color:var(--ion);}
.ax-chat-newgroup:hover{border-color:var(--ion);color:var(--text);}

/* --- resources: the whole card is the door (2026-07-31) ------------ */
a.resource-block{transition:border-color .16s ease,transform .16s ease,box-shadow .16s ease;}
a.resource-block:hover{border-color:var(--ion)!important;transform:translateY(-2px);box-shadow:0 14px 34px -18px rgba(var(--ion-rgb),.6);}
