/* FullSquad design system v3 (v0.14: Apple format reskin).
   Idiom lifted from the approved mockups-apple/ designs, which
   follow the KeyBro app: iOS system gray page, white inset grouped
   cards (18px radius, no colored borders, one soft shadow), hairline
   separators, large titles, quiet gray uppercase section labels,
   TRUE iOS segmented controls (gray track, white selected pill,
   accent label), pill buttons, filled iOS inputs, and a translucent
   blurred tab bar. Brand unchanged: pitch green #0E7A3D, lime meter
   accent #B5E048, deep navy #12212B; the organizer side themes its
   accent to blue #2563EB through the same variables. */
* { margin:0; padding:0; box-sizing:border-box; -webkit-font-smoothing:antialiased; -webkit-tap-highlight-color:transparent; }
:root {
  --green:#0E7A3D; --green-hi:#12914A; --green-dark:#0A5C2E; --green-deep:#095C2C;
  --navy:#12212B; --lime:#B5E048; --lime-bg:#F0F9D8; --lime-text:#5C7A0B;
  --hot:#E4572E; --red:#B3372C; --ink:#1C1C1E; --ink2:#3A3A3C; --muted:#6E6E73; --faint:#AEAEB2;
  --line:rgba(60,60,67,.12); --card:#fff; --fill:#F2F2F7; --track:rgba(118,118,128,.12);
  --ground:#F2F2F7;
  --shadow:0 1px 2px rgba(16,24,20,.04), 0 10px 28px -22px rgba(16,24,20,.30);
  --shadow-sm:0 1px 2px rgba(16,24,20,.05), 0 4px 14px -8px rgba(16,24,20,.16);
  --head-h:68px;
  --tabbar-h:68px;
  /* Safe areas: every fixed/sticky surface pads by these, so nothing
     ever sits under the clock or the home indicator, on any phone. */
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
}
html { scroll-behavior:smooth; }
body { background:var(--ground); font-family:-apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; color:var(--ink); }
.wrap { max-width:600px; margin:0 auto; padding:16px 16px 44px; animation:pagein .3s ease both; }
body.with-tabbar .wrap { padding-bottom:calc(var(--tabbar-h) + var(--sab) + 28px); }
/* Repeat tab navigation in one session skips the entrance motion:
   the page is simply there, which is most of "fast". */
html.fs-warm .wrap { animation:none; }
html.fs-warm .meter i { animation-duration:.3s; }
@keyframes pagein { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:none; } }
a { color:var(--green); }
button, .chip, .btn, a.card-link { transition:transform .12s ease, background-color .15s ease, border-color .15s ease, box-shadow .15s ease; }
button:active, .chip:active, .btn:active { transform:scale(.97); }

/* ---- brand + header ---- */
.logo { display:flex; align-items:center; gap:10px; text-decoration:none; color:var(--ink); }
.logo .name { font-size:22px; font-weight:800; letter-spacing:-.5px; color:var(--navy); }
.logo .name em { font-style:normal; color:var(--green); }
.ball { display:inline-flex; align-items:center; justify-content:center; background:linear-gradient(160deg, var(--green-hi), var(--green-deep)); border-radius:12px; flex:none; width:38px; height:38px; box-shadow:inset 0 1px 0 rgba(255,255,255,.25), 0 4px 10px -4px rgba(9,92,44,.55); }
.loc { font-size:12.5px; color:var(--muted); margin-top:3px; font-weight:600; }
/* The browse heading is a large title (v0.14): "Games near you" in
   ink, the selected city riding after it in gray. */
#locLine { font-size:32px; font-weight:800; letter-spacing:-.7px; line-height:1.12; color:var(--ink); }
#locLine .dim { color:var(--muted); font-weight:700; }
/* The brand row sits fully below the phone's status bar with real
   breathing room (v0.10): the native wrapper insets the WebView off
   the bars, the safe area var covers browser chrome, and the fixed
   padding below keeps the logo comfortably placed, never jammed
   against the top. The bar itself is the iOS translucent blur
   (v0.14): near white at 86 percent over a 20px saturate blur, with
   a hairline under it. */
.appbar { position:sticky; top:0; z-index:40; margin:-16px -16px 0; padding:calc(16px + var(--sat)) 16px 12px; background:rgba(249,249,251,.86); backdrop-filter:blur(20px) saturate(1.6); -webkit-backdrop-filter:blur(20px) saturate(1.6); border-bottom:.5px solid var(--line); }
.appbar-in { display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:12px; max-width:600px; margin:0 auto; }
/* The brand always sits in the app bar's center slot (v0.9): the two
   side slots are equal 1fr columns, so a back button, a page title,
   or a badge can never push the logo off center. */
.bar-side { display:flex; align-items:center; min-width:0; }
.bar-side.right { justify-content:flex-end; }

/* ---- organizer theme (v0.10) ----
   Same app, second identity. Player pages keep the pitch green;
   organizer pages (sign in, sign up, dashboard) and the admin
   console carry class="theme-org" on the body and swap the whole
   palette to deep navy and blue through the same variables, so a
   signed in organizer can tell at a glance which side of the app
   they are on. Switching is by PAGE, never by sign in state, so
   there is no mixed moment. The logo's own colors are brand and are
   pinned back to green below: only the chrome around it themes.
   v0.14: the organizer ground keeps its faint blue tint (#EEF2F7 in
   the organizer mockup); hairlines stay the shared iOS separator. */
body.theme-org {
  --green:#2563EB; --green-hi:#3B82F6; --green-dark:#1D4ED8; --green-deep:#1E3A8A;
  --lime:#38BDF8; --lime-bg:#E0F2FE; --lime-text:#0369A1;
  --ground:#EEF2F7;
}
body.theme-org .appbar { background:rgba(246,248,251,.86); }
body.theme-org .filterbar { background:rgba(246,248,251,.86); }
body.theme-org .badge { background:#E3ECFD; color:var(--green); }
body.theme-org .state.hold { background:#E3ECFD; color:var(--green); }
body.theme-org .state.on { background:#E3ECFD; color:var(--green); }
body.theme-org .avatar { background:#E3ECFD; }
body.theme-org .manage-btn.open { background:#E3ECFD; }
body.theme-org :focus-visible { outline-color:rgba(37,99,235,.5); }
body.theme-org .ball { background:linear-gradient(160deg, #12914A, #095C2C); }
body.theme-org .logo .name em { color:#0E7A3D; }
.subbar { display:flex; align-items:center; gap:12px; }
.pagetitle { font-size:15px; font-weight:700; color:var(--muted); }

/* ---- type ---- */
h1 { font-size:32px; font-weight:800; letter-spacing:-.7px; line-height:1.12; }
h2 { font-size:18px; font-weight:800; letter-spacing:-.2px; }
.sub { font-size:14px; color:var(--muted); font-weight:500; margin-top:3px; line-height:1.45; }
.eyebrow { font-size:11.5px; font-weight:800; letter-spacing:.7px; color:var(--muted); text-transform:uppercase; }

/* ---- cards ---- */
.card { background:var(--card); border:none; border-radius:18px; padding:16px; box-shadow:var(--shadow); margin-top:12px; }
/* Quiet secondary blocks: one primary card per screen keeps the full
   treatment; the rest sit flatter, as inset grouped lists with a
   hairline and no shadow. */
.card.flat { background:#fff; border:1px solid var(--line); box-shadow:none; }
/* The trust facts inside the join form read as the mockup's filled
   inset box, not a second card floating inside the first. */
#joinCard .card.flat { background:var(--fill); border:none; border-radius:12px; box-shadow:none; }
a.card-link { display:block; text-decoration:none; color:inherit; }
a.card-link:active .card { transform:scale(.99); }

/* ---- game card (browse) ---- */
.gcard-top { display:flex; justify-content:space-between; align-items:center; gap:8px; }
.gcard-when { font-size:12.5px; font-weight:800; letter-spacing:.5px; color:var(--green); text-transform:uppercase; }
.gcard-when.hot { color:var(--hot); }
.gcard-title { font-size:20px; font-weight:800; letter-spacing:-.3px; margin-top:6px; line-height:1.2; }
.gcard-venue { display:flex; align-items:center; gap:5px; font-size:14.5px; color:var(--muted); font-weight:500; margin-top:4px; }
.gcard-venue svg { flex:none; }
.gcard-meta { display:flex; gap:6px; margin-top:12px; align-items:center; flex-wrap:wrap; }
.gcard-price { margin-left:auto; text-align:right; }
.gcard-price .amt { font-size:20px; font-weight:800; letter-spacing:-.3px; }
.gcard-price .per { font-size:12px; color:var(--muted); font-weight:600; }
.gcard-meter { margin-top:14px; }
.gcard-line { font-size:14px; font-weight:600; margin-top:8px; }
.gcard-line .dim { color:var(--muted); font-weight:600; }

/* badges: neutral gray capsules (v0.14). Meaning keeps its color:
   the navy Private capsule, the amber warning, the admin Owner. */
.badge { display:inline-flex; align-items:center; gap:5px; font-size:12px; font-weight:600; letter-spacing:0; padding:4px 9px; border-radius:999px; background:var(--fill); color:var(--ink2); text-transform:none; white-space:nowrap; }
.badge.lime { background:var(--fill); color:var(--ink2); }
.badge.gray { background:var(--fill); color:var(--muted); }
.badge.dark { background:var(--navy); color:#fff; font-weight:700; }
.badge.warn { background:#FFF4E0; color:#9A6A00; }
.badge.lock { background:var(--navy); color:#fff; font-weight:700; }

/* ---- filter bar (browse) ---- */
.filterbar { position:sticky; top:calc(var(--head-h) + var(--sat)); z-index:39; margin:0 -16px; padding:10px 16px 8px; background:rgba(249,249,251,.86); backdrop-filter:blur(20px) saturate(1.6); -webkit-backdrop-filter:blur(20px) saturate(1.6); }
/* ---- the one pill (v0.11, restyled v0.14) ----
   Every standalone chip and filter row is built from this one
   component: white pill, hairline border, dark label; selected is
   filled in the side's brand color with white text, exactly as the
   browse mockup's filter pills render. Rows either wrap or scroll
   with an edge fade; they never sit cramped or touching. */
.chiprow { display:flex; gap:10px; overflow-x:auto; scrollbar-width:none; -ms-overflow-style:none; margin:2px -16px 0; padding:4px 16px 6px; -webkit-mask-image:linear-gradient(90deg, #000 calc(100% - 28px), transparent); mask-image:linear-gradient(90deg, #000 calc(100% - 28px), transparent); }
.chiprow::-webkit-scrollbar { display:none; }
.chips { display:flex; gap:10px; margin:14px 0 2px; flex-wrap:wrap; }
.chip { display:inline-flex; align-items:center; justify-content:center; min-height:38px; padding:0 15px; border-radius:999px; background:#fff; border:1px solid rgba(60,60,67,.16); font-size:14px; font-weight:600; line-height:1; color:var(--ink); cursor:pointer; white-space:nowrap; font-family:inherit; flex:none; }
.chip.on { background:var(--green); border-color:var(--green); color:#fff; }
.chip.icon { gap:6px; }
/* The browse All / Public / Private row is a TRUE iOS segmented
   control (v0.14), not chips: gray track, white selected pill with
   the soft shadow, accent label. The buttons keep their .chip class
   and data hooks; only the presentation changes, scoped here. */
#visChips { width:max-content; max-width:100%; margin-left:auto; margin-right:auto; overflow:visible; background:var(--track); border-radius:10px; padding:2px; gap:2px; -webkit-mask-image:none; mask-image:none; }
#visChips .chip { min-width:92px; min-height:34px; padding:5px 14px; border:none; border-radius:8px; background:transparent; font-size:13.5px; box-shadow:none; }
#visChips .chip.on { background:#fff; color:var(--green); font-weight:700; box-shadow:0 3px 8px rgba(0,0,0,.12), 0 0 1px rgba(0,0,0,.06); }
.filterpanel { margin-top:10px; background:#fff; border:none; border-radius:18px; padding:14px; box-shadow:var(--shadow); }
.filterpanel .row { align-items:flex-end; }
.filterpanel label.f { margin-top:0; }

/* ---- meters ---- */
.meter { height:8px; border-radius:99px; background:#E9E9EC; overflow:hidden; }
.meter i { display:block; height:100%; background:linear-gradient(90deg, var(--green) 55%, var(--lime)); border-radius:99px; transform-origin:left center; animation:fillin .9s cubic-bezier(.22,.8,.3,1) both; }
.meter.hot i { background:linear-gradient(90deg, var(--hot), #F08A5D); }
.meter.big { height:10px; }
/* The organizer's next game card keeps the brand meter even on the
   blue side (organizer mockup); every other organizer meter runs
   accent blue to sky through the themed variables above. */
#nextGame .meter i { background:linear-gradient(90deg, #0E7A3D 55%, #B5E048); }
@keyframes fillin { from { transform:scaleX(0); } to { transform:scaleX(1); } }

/* ---- buttons: full pills (v0.14) ---- */
.btn { display:flex; align-items:center; justify-content:center; gap:8px; border-radius:999px; font-weight:700; font-size:16.5px; min-height:52px; padding:13px 16px; border:none; cursor:pointer; width:100%; font-family:inherit; text-decoration:none; }
.btn.primary { background:var(--green); color:#fff; }
.btn.primary:active { background:var(--green-dark); }
.btn.ghost { background:#fff; border:1.5px solid rgba(60,60,67,.20); color:var(--ink); }
.btn.danger { background:#fff; border:1.5px solid #F0B8AC; color:var(--red); }
.btn.small { font-size:14px; padding:10px 16px; min-height:44px; width:auto; }
.btn:disabled { opacity:.55; cursor:default; }
/* Manage dropdown toggle: the chevron flips and the button fills
   while its panel is open, so it reads as a dropdown opening under
   the card, never as a page change. */
.manage-btn .chev { display:inline-block; font-size:12px; line-height:1; transition:transform .18s ease; }
.manage-btn.open { background:#E3F0E6; border-color:var(--green); color:var(--green-dark); }
.manage-btn.open .chev { transform:rotate(180deg); }
.manage-panel { animation:fs-slide-down .22s ease; transform-origin:top center; }
@keyframes fs-slide-down { from { opacity:0; transform:translateY(-6px) scaleY(.98); } to { opacity:1; transform:none; } }
/* Wallet buttons carry the real marks (v0.11): Apple Pay is the
   black button with the white Apple mark, Google Pay the white
   button with the four color G, both at the same height, radius,
   and weight as every other primary button, so they read as the
   payment buttons people already trust everywhere else. Their
   marks and colors are exact and unchanged in v0.14. */
.btn.wallet-apple { background:#000; color:#fff; box-shadow:none; gap:7px; font-size:17px; }
.btn.wallet-google { background:#fff; border:1px solid #DADCE0; color:#3C4043; box-shadow:none; margin-top:8px; gap:7px; font-size:17px; font-weight:600; }
.btn.wallet-apple svg, .btn.wallet-google svg { display:block; flex:none; }

/* ---- forms: iOS filled inputs (v0.14) ---- */
.row { display:flex; gap:10px; } .row > * { flex:1; }
label.f { display:block; font-size:13px; font-weight:600; color:var(--muted); text-transform:uppercase; letter-spacing:.02em; margin:16px 0 7px; }
input, select, textarea { width:100%; padding:13px 14px; border:1px solid rgba(60,60,67,.10); border-radius:12px; font-size:16px; font-family:inherit; color:var(--ink); background:var(--fill); }
input, select { min-height:50px; }
input[type="checkbox"] { width:auto; min-height:0; padding:0; }
input:focus, select:focus, textarea:focus { outline:none; background:#fff; border-color:var(--green); box-shadow:0 0 0 3px rgba(60,60,67,.10); }
.note { font-size:13px; color:var(--muted); font-weight:500; line-height:1.5; }
.error { background:#FDECEA; color:var(--red); border-radius:12px; padding:12px 14px; font-size:14px; font-weight:600; margin-top:12px; line-height:1.45; }
.okbox { background:#E3F0E6; color:var(--green-deep); border-radius:12px; padding:12px 14px; font-size:14px; font-weight:600; margin-top:12px; line-height:1.45; }
.warnbox { background:#FFF4E0; color:#7A5200; border-radius:12px; padding:12px 14px; font-size:14px; font-weight:600; margin-top:12px; line-height:1.45; }
.warnbanner { background:#FFF4E0; color:#7A5200; border:none; border-radius:12px; padding:12px 14px; font-size:14px; font-weight:700; line-height:1.45; }
/* Quiet informational note box (the mockup's filled inset): used by
   the ID gate, fee ledger, reset link and sent payment notes. */
.pill-note { background:var(--fill); color:var(--ink2); border-radius:12px; padding:11px 13px; font-size:13.5px; font-weight:600; line-height:1.5; }

/* ---- segmented control (v0.14): TRUE iOS pattern ----
   A light gray track; the selected option is a WHITE pill with a
   soft shadow and its label in the side's accent color; unselected
   labels are dark. Used for the auth toggle, the organizer main
   tabs, the create form's mode and visibility, the manage panel's
   sub tabs and Who can join, and the spot screen's tabs, so every
   "pick one" in the app reads the same way. */
.seg { display:flex; background:var(--track); border:none; border-radius:10px; padding:2px; gap:2px; }
.seg button { flex:1; display:flex; align-items:center; justify-content:center; gap:6px; min-height:34px; padding:5px 10px; border-radius:8px; font-size:13.5px; font-weight:600; line-height:1.2; text-align:center; color:var(--ink); background:transparent; border:none; cursor:pointer; font-family:inherit; }
.seg button.on { background:#fff; color:var(--green); font-weight:700; box-shadow:0 3px 8px rgba(0,0,0,.12), 0 0 1px rgba(0,0,0,.06); }
.seg button:active { transform:none; }
.seg button .n { font-size:11.5px; font-weight:800; background:rgba(18,33,43,.07); color:var(--ink); border-radius:99px; padding:3px 7px; line-height:1; }
.seg button.on .n { background:rgba(18,33,43,.08); }

/* ---- lists, roster, states ---- */
/* Status pills carry meaning, so they keep tinted treatments: the
   mockup's Paid and Filling are light accent capsules with accent
   text; waiting stays amber, problems stay red. */
.state { font-size:12px; font-weight:700; padding:4px 10px; border-radius:999px; white-space:nowrap; background:var(--fill); color:var(--ink2); }
.state.hold { background:#E3F0E6; color:var(--green-deep); }
.state.on { background:#E3F0E6; color:var(--green-deep); }
.state.wait { background:#FFF4E0; color:#9A6A00; }
.state.move { background:#E8F0FE; color:#2B50B0; }
.state.off { background:var(--fill); color:var(--muted); }
.state.bad { background:#FDECEA; color:var(--red); }
.roster-row { display:flex; align-items:center; gap:11px; padding:9px 0; border-bottom:1px solid var(--line); }
.roster-row:last-child { border-bottom:none; }
.avatar { border-radius:50%; background:#E3F0E6; color:var(--green); font-weight:700; display:flex; align-items:center; justify-content:center; flex:none; width:38px; height:38px; font-size:14px; }
.grow { display:flex; align-items:center; gap:10px; padding:11px 0; border-bottom:1px solid var(--line); }
.grow:last-child { border-bottom:none; }

/* The spot screen's Updates log: no box, just quiet divider rows. */
.updates { margin-top:20px; }
.updates .updhead { font-size:13px; font-weight:600; letter-spacing:.02em; color:var(--muted); text-transform:uppercase; }
.noterow { padding:8px 0; border-bottom:1px solid var(--line); font-size:13.5px; line-height:1.45; }
.noterow:last-child { border-bottom:none; }
.noterow .notetime { color:var(--faint); font-size:12px; font-weight:600; white-space:nowrap; margin-left:6px; }
/* A quiet text-only action, for things like giving up a spot: easy to
   find at the bottom of a screen, never the loudest thing on it. */
.textbtn { display:block; margin:22px auto 0; background:none; border:none; color:var(--red);
  font-size:13.5px; font-weight:700; padding:10px 16px; min-height:44px; cursor:pointer; }
/* The rating block's stars (v0.9): big quiet tap targets; a tap sends
   the rating, there is no hover state to set. */
.stars { display:flex; gap:2px; margin-top:6px; }
.starb { background:none; border:none; font-size:30px; line-height:1; color:#D1D1D6;
  padding:6px 4px; min-width:44px; min-height:44px; cursor:pointer; }
.starb:active { color:var(--green); }
.step { display:flex; gap:11px; align-items:flex-start; margin-top:8px; }
.step .n { width:24px; height:24px; border-radius:50%; background:var(--green); color:#fff; font-size:13px; font-weight:800; display:flex; align-items:center; justify-content:center; flex:none; margin-top:1px; }
.step span { font-size:14px; font-weight:600; line-height:1.35; }
.section-label { font-size:13px; font-weight:600; letter-spacing:.02em; color:var(--muted); text-transform:uppercase; margin-top:12px; }

/* ---- kpis (admin) ---- */
.kpis { display:grid; grid-template-columns:1fr 1fr; gap:11px; margin-top:12px; }
.kpi { background:#fff; border:none; border-radius:18px; padding:13px 14px; box-shadow:var(--shadow); }
.kpi .k { font-size:11.5px; font-weight:700; color:var(--muted); text-transform:uppercase; letter-spacing:.5px; }
.kpi .v { font-size:23px; font-weight:800; margin-top:3px; letter-spacing:-.3px; }
.kpi .s { font-size:12px; color:var(--green); font-weight:600; margin-top:1px; }

/* ---- messages ---- */
.msg { max-width:82%; padding:10px 13px; border-radius:18px; font-size:14.5px; line-height:1.4; margin-top:8px; white-space:pre-wrap; word-break:break-word; }
.msg.them { background:#E9E9EB; color:var(--ink); align-self:flex-start; }
.msg.me { background:var(--green); color:#fff; align-self:flex-end; }
.msg.broadcast { background:#E3F0E6; color:var(--ink); align-self:stretch; max-width:100%; }
.msgs { display:flex; flex-direction:column; }

/* ---- collapsible "more" ---- */
details.more { margin-top:14px; }
details.more summary { font-size:14px; font-weight:700; color:var(--green); cursor:pointer; padding:6px 0; list-style:none; }
details.more summary::-webkit-details-marker { display:none; }
details.morecard { background:#fff; border:none; border-radius:18px; box-shadow:var(--shadow); padding:2px 16px 14px; margin-top:14px; }
details.morecard summary { display:flex; align-items:center; justify-content:space-between; padding:14px 0 4px; color:var(--navy); font-size:15px; }
details.morecard summary .chev { transition:transform .2s ease; color:var(--muted); flex:none; }
details.morecard[open ] summary .chev { transform:rotate(180deg); }
details.morecard summary .hint { display:block; font-size:12.5px; font-weight:500; color:var(--muted); margin-top:2px; }

/* ---- misc components ---- */
.tabs { display:flex; gap:6px; margin-top:14px; flex-wrap:wrap; }
.hidden { display:none !important; }
.bigcheck { width:64px; height:64px; border-radius:50%; background:var(--green); display:flex; align-items:center; justify-content:center; margin:10px auto; box-shadow:0 10px 22px -8px rgba(16,24,20,.35); }
.footer-note { text-align:center; font-size:12px; color:var(--faint); font-weight:500; margin-top:22px; line-height:1.5; }
table.plain { width:100%; border-collapse:collapse; font-size:13.5px; }
table.plain td, table.plain th { padding:8px 4px; border-bottom:1px solid var(--line); text-align:left; vertical-align:top; }
.backbtn { width:44px; height:44px; border-radius:50%; background:rgba(118,118,128,.12); border:none; display:flex; align-items:center; justify-content:center; flex:none; text-decoration:none; }
.codebox { font-size:30px; font-weight:800; letter-spacing:6px; text-align:center; background:var(--fill); color:var(--ink); border-radius:12px; padding:14px 10px; margin-top:8px; }
.codeinput { text-transform:uppercase; letter-spacing:4px; font-weight:700; text-align:center; }
.trust { display:flex; gap:10px; align-items:center; background:var(--fill); border:none; border-radius:12px; padding:13px 14px; margin-top:16px; }
.trust svg { flex:none; }
.trust span { font-size:13.5px; font-weight:600; color:var(--ink2); line-height:1.45; }

/* ---- browse footer + centered pill row (v0.13, restyled v0.14) ---- */
.chiprow.centered { justify-content:center; -webkit-mask-image:none; mask-image:none; }
.browsefoot { margin-top:32px; }
.browsefoot .footrow { display:flex; gap:12px; }
.browsefoot .footrow .btn { flex:1; width:auto; font-size:15px; padding:13px 8px; white-space:nowrap; }
.btn.dark { background:#1C1C1E; color:#fff; }
.btn.light { background:#fff; border:1.5px solid rgba(60,60,67,.22); color:var(--ink); }
.browsefoot .btn.wide { margin-top:12px; }
.browsefoot .soon { text-align:center; margin-top:26px; font-size:12.5px; font-weight:700; letter-spacing:2.5px; color:var(--muted); }
.browsefoot .soonmarks { display:flex; justify-content:center; align-items:center; gap:14px; margin-top:10px; }
.browsefoot .footlinks { display:flex; justify-content:center; gap:24px; margin-top:30px; padding:0 4px; }
.browsefoot .footlinks a { color:var(--muted); font-size:14px; font-weight:500; text-decoration:none; }

/* ---- legal pages (v0.13) ---- */
.legal h2 { margin:24px 0 8px; font-size:17px; font-weight:800; }
.legal p, .legal li { font-size:14.5px; line-height:1.65; color:#334155; }
.legal p { margin-top:8px; }
.legal ul { padding-left:20px; margin-top:8px; }
.legal li { margin-top:4px; }
.empty { text-align:center; padding:34px 22px 30px; }
.empty .mark { width:72px; height:72px; border-radius:22px; margin:0 auto; background:linear-gradient(160deg, var(--green-hi), var(--green-deep)); display:flex; align-items:center; justify-content:center; box-shadow:0 14px 26px -12px rgba(9,92,44,.6); }
.empty h2 { margin-top:16px; font-size:19px; }
.empty p { font-size:14px; color:var(--muted); font-weight:500; line-height:1.5; margin-top:6px; }

/* skeleton cards while the list loads: same shapes as the real
   cards, so content fades in without anything jumping (v0.11) */
.skel { border-radius:18px; background:#fff; border:none; box-shadow:var(--shadow); padding:16px; margin-top:12px; }
.skel i { display:block; border-radius:8px; background:linear-gradient(90deg, #E9E9EC 25%, #F2F2F7 50%, #E9E9EC 75%); background-size:200% 100%; animation:shimmer 1.2s linear infinite; }
.skel .skelrow { display:flex; gap:10px; align-items:flex-start; }
.skel .grow { flex:1; }
.fadein { animation:fs-fade .28s ease both; }
@keyframes fs-fade { from { opacity:0 } to { opacity:1 } }
/* Section titles are quiet gray uppercase labels everywhere
   (v0.14, the mockups' seclabel): one margin, one weight, one
   rhythm. */
.secttl { font-size:13px; font-weight:600; letter-spacing:.02em; text-transform:uppercase; color:var(--muted); margin:26px 4px 8px; }
.secttl:first-child { margin-top:6px; }
@keyframes shimmer { from { background-position:180% 0; } to { background-position:-20% 0; } }

/* ---- bottom tab bar (player side): translucent iOS bar (v0.14) ---- */
.tabbar { position:fixed; left:0; right:0; bottom:0; z-index:50; background:rgba(249,249,249,.86); backdrop-filter:blur(20px) saturate(1.6); -webkit-backdrop-filter:blur(20px) saturate(1.6); border-top:.5px solid var(--line); padding-bottom:calc(var(--sab) + 4px); }
.tabbar-in { max-width:600px; margin:0 auto; display:flex; }
.tabbar a { flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px; min-height:52px; padding:8px 2px 7px; text-decoration:none; color:#8E8E93; font-size:10.5px; font-weight:600; letter-spacing:.1px; text-align:center; }
.tabbar a svg { display:block; width:24px; height:24px; padding:0; border-radius:0; background:none; transition:background-color .15s ease; }
.tabbar a.on { color:var(--green); }
.tabbar a.on svg { background:none; }
.tabbar a:active { transform:none; }

/* ---- launch intro: the plain Apple white (v0.14), staged slower
   in v0.15. Beat one: the wordmark lands large, zooms out and
   settles over 1.2s. Beat two: the tagline fades in beside it from
   1.4s over 0.8s. Nothing else. ---- */
#launch { position:fixed; inset:0; z-index:100; display:flex; align-items:center; justify-content:center;
  padding:calc(20px + var(--sat)) 18px calc(20px + var(--sab));
  background:#fff;
  transition:opacity .5s ease, transform .5s ease; }
#launch.done { opacity:0; transform:translateY(-10px); pointer-events:none; }
#launch .lw { display:flex; align-items:center; gap:16px; max-width:100%; }
#launch .lword { font-size:44px; font-weight:800; letter-spacing:-1.2px; color:var(--navy); white-space:nowrap;
  transform-origin:left center; animation:lzoom 1.2s cubic-bezier(.25,.8,.3,1) both; }
#launch .lword em { font-style:normal; color:var(--green); }
@keyframes lzoom { 0% { transform:scale(1.7); opacity:0; } 22% { opacity:1; } 100% { transform:scale(1); opacity:1; } }
#launch .ltag { font-size:15px; font-weight:700; line-height:1.35; color:var(--muted);
  border-left:2px solid rgba(14,122,61,.5); padding-left:14px; max-width:150px;
  animation:ltagin .8s 1.4s ease both; }
#launch { overflow:hidden; }
@media (max-width: 480px) {
  #launch .lw { gap:12px; }
  #launch .lword { font-size:35px; letter-spacing:-.9px; }
  #launch .ltag { font-size:13.5px; max-width:126px; padding-left:11px; }
}
@keyframes ltagin { from { opacity:0; transform:translateX(8px); } to { opacity:1; transform:none; } }
/* ---- success confirmation (shared, assets/chrome.js FS.confirm) ----
   One calm payoff for every landed submission (v0.14): the check in
   its green circle over a white sheet style card carrying the label.
   It never takes input (pointer-events none), so the real success
   state underneath is always reachable. */
.fs-confirm { position:fixed; inset:0; z-index:120; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px;
  pointer-events:none; transition:opacity .25s ease, transform .25s ease; }
.fs-confirm.done { opacity:0; transform:scale(.96); }
.fs-confirm-bubble { width:84px; height:84px; border-radius:50%; position:relative;
  background:var(--green);
  display:flex; align-items:center; justify-content:center;
  box-shadow:0 18px 34px -12px rgba(16,24,20,.35);
  animation:fs-pop .38s cubic-bezier(.2,.9,.3,1.3) both; }
.fs-confirm-bubble::after { content:''; position:absolute; inset:-9px; border-radius:50%;
  border:3px solid var(--lime); opacity:0; animation:fs-ring .55s .1s ease-out both; }
@keyframes fs-pop { from { transform:scale(.5); opacity:0; } to { transform:scale(1); opacity:1; } }
@keyframes fs-ring { from { opacity:.9; transform:scale(.82); } to { opacity:0; transform:scale(1.12); } }
.fs-confirm-bubble .fs-check-path { stroke-dasharray:26; stroke-dashoffset:26; animation:fs-draw .32s .18s ease-out forwards; }
@keyframes fs-draw { to { stroke-dashoffset:0; } }
.fs-confirm-label { font-size:16px; font-weight:800; letter-spacing:-.2px; color:var(--ink);
  background:#fff; padding:12px 18px; border-radius:18px; box-shadow:var(--shadow);
  animation:fs-label .3s .12s ease both; }
@keyframes fs-label { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }

/* ---- join flow: the summary folded into the join card (v0.14) ----
   The old pinned strip is now the card's own header block: a filled
   inset at the top of the join card carrying the game and the
   price, exactly as the game mockup folds it in. Same element, same
   classes, no longer sticky. */
.joinbar { margin:0 0 14px; padding:12px 14px; background:var(--fill); border:none; border-radius:12px; }
.joinbar .t { font-size:15.5px; font-weight:800; letter-spacing:-.2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.joinbar .m { font-size:12.5px; font-weight:700; color:var(--green); margin-top:1px; }
#joinCard { transition:opacity .25s ease; }
#joinCard.busy { opacity:.5; pointer-events:none; }
.doneenter { animation:pagein .35s ease both; }
.btn.processing { animation:fs-pulse 1s ease-in-out infinite; }
@keyframes fs-pulse { 0%,100% { transform:scale(1); } 50% { transform:scale(.985); } }

/* ---- form affordances (v0.6 polish) ---- */
:focus-visible { outline:3px solid rgba(14,122,61,.5); outline-offset:2px; border-radius:8px; }
.backbtn { width:44px; height:44px; }
.pwwrap { position:relative; }
.pwwrap input { padding-right:56px; }
.pweye { position:absolute; right:4px; top:50%; transform:translateY(-50%); min-width:48px; min-height:48px;
  display:flex; align-items:center; justify-content:center; background:transparent; border:none; cursor:pointer;
  color:var(--muted); font-size:12px; font-weight:800; letter-spacing:.3px; border-radius:12px; font-family:inherit; }
.pweye:active { transform:translateY(-50%) scale(.94); }
.fielderror { color:var(--red); font-size:12.5px; font-weight:600; margin-top:5px; line-height:1.4; }
input[aria-invalid="true"], select[aria-invalid="true"] { border-color:var(--red); box-shadow:0 0 0 3px rgba(179,55,44,.14); }
.forgotlink { display:inline-block; margin-top:12px; font-size:14px; font-weight:700; min-height:48px; line-height:48px; }
.quickchips { display:flex; gap:10px; margin:2px 0 4px; flex-wrap:wrap; }
.btn.working { opacity:.65; pointer-events:none; }

/* ---- visibility info button + explainer sheet ---- */
.infoi { display:inline-flex; align-items:center; justify-content:center; width:32px; height:32px;
  margin:-6px -4px -6px 0; background:transparent; border:none; cursor:pointer; vertical-align:middle; flex:none; }
.infoi i { display:flex; align-items:center; justify-content:center; width:19px; height:19px; border-radius:50%;
  border:1.6px solid #C7C7CC; color:var(--muted); font-size:11.5px; font-weight:800; font-style:normal; line-height:1; background:#fff; }
.sheetwrap { position:fixed; inset:0; z-index:90; background:rgba(0,0,0,.4); display:flex; align-items:flex-end; justify-content:center; }
.sheet { background:#fff; width:100%; max-width:560px; border-radius:20px 20px 0 0; padding:20px 20px calc(18px + var(--sab));
  animation:sheetup .28s cubic-bezier(.2,.9,.3,1) both; }
@keyframes sheetup { from { transform:translateY(26px); opacity:.4; } to { transform:none; opacity:1; } }
.sheet h3 { font-size:17.5px; letter-spacing:-.2px; margin-bottom:6px; }
.sheet p { font-size:14.5px; line-height:1.55; color:var(--muted); font-weight:500; margin-top:8px; }
.sheet p strong { color:var(--ink); }

/* ---- alt payments (Zelle, manual confirm; pre-switch Cash App spots reuse it) ---- */
.paychoice { display:flex; gap:6px; flex-wrap:wrap; }
.paypanel { background:#fff; border:none; border-radius:18px; padding:16px; margin-top:12px; box-shadow:var(--shadow); }
.paypanel .dest { font-size:19px; font-weight:800; letter-spacing:-.2px; word-break:break-all; }
.payref { font-size:21px; font-weight:800; letter-spacing:3px; color:var(--green-dark); }
.pendbox { background:#FFF4E0; border:none; border-radius:12px; padding:12px 14px; margin-top:12px; }
.pendbox .t { font-weight:800; color:#7A5200; font-size:14.5px; }
.pendbox .s { font-size:13px; color:#7A5200; font-weight:500; margin-top:3px; line-height:1.45; }

@media (prefers-reduced-motion: reduce) {
  .wrap { animation:none; }
  .meter i { animation:none; }
  #launch .lword, #launch .ltag { animation-duration:.01s; animation-delay:0s; }
  .fs-confirm-bubble, .fs-confirm-bubble::after, .fs-confirm-label, .btn.processing { animation-duration:.01s; }
  .fs-confirm-bubble .fs-check-path { animation-duration:.01s; animation-delay:0s; }
  #joinCard { transition:none; }
  .doneenter { animation:none; }
  .manage-panel { animation:none; }
  .manage-btn .chev { transition:none; }
}

/* ---- v0.16: photo cards, game hero, agreement, photo row ---- */
.pcard { background:var(--card); border-radius:18px; box-shadow:var(--shadow); margin-top:14px; overflow:hidden; }
.pcard .photo { position:relative; height:198px; }
.pcard .photo img { width:100%; height:100%; object-fit:cover; display:block; }
.sporttag { position:absolute; top:12px; left:12px; display:inline-flex; align-items:center; gap:6px;
  background:rgba(18,33,43,.78); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  color:#fff; font-size:12.5px; font-weight:700; padding:6px 11px; border-radius:999px; }
.sporttag .dot { width:7px; height:7px; border-radius:50%; background:var(--lime); flex:none; }
.pcard .pbody { padding:14px 16px 16px; }
.hero-photo { position:relative; height:220px; border-radius:18px; overflow:hidden; margin-top:12px; box-shadow:var(--shadow); }
.hero-photo img { width:100%; height:100%; object-fit:cover; display:block; }
.agreeline { display:flex; gap:10px; align-items:flex-start; background:var(--fill); border-radius:12px; padding:12px; margin-top:14px; cursor:pointer; }
.agreeline input { width:22px; height:22px; flex:none; margin-top:1px; accent-color:var(--green); }
.agreeline span { font-size:14px; line-height:1.45; }
.photorow { display:flex; align-items:center; gap:12px; }
.photothumb { width:64px; height:64px; border-radius:12px; object-fit:cover; flex:none; background:var(--fill); }
