From 5c09266d75b84ca0e134a89930861096b728a953 Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Sat, 5 Sep 2026 19:19:46 -0700 Subject: [PATCH] fix player win % and visual overhaul --- boker/db_models.py | 2 + boker/routes/leagues.py | 130 +- .../versions/0006_league_default_buyin.py | 43 + .../versions/0007_league_default_rebuy.py | 43 + static/css/style.css | 2298 +++++++++++++---- static/css/tokens.css | 137 +- templates/landing.html | 541 +--- templates/league_dashboard.html | 350 ++- templates/league_leaderboard.html | 138 +- templates/league_players.html | 70 +- templates/league_session_detail.html | 394 ++- templates/league_session_view.html | 2 +- templates/league_sessions.html | 8 +- templates/league_settings.html | 14 + templates/leagues_index.html | 407 ++- tests/test_stats.py | 36 + 16 files changed, 3123 insertions(+), 1490 deletions(-) create mode 100644 migrations/versions/0006_league_default_buyin.py create mode 100644 migrations/versions/0007_league_default_rebuy.py diff --git a/boker/db_models.py b/boker/db_models.py index a0da8d9..a88e1ac 100644 --- a/boker/db_models.py +++ b/boker/db_models.py @@ -98,6 +98,8 @@ class League(TimestampMixin, db.Model): archived_at = db.Column(db.DateTime(timezone=True), nullable=True) eligible_min_sessions = db.Column(db.Integer, nullable=False, default=3) break_even_cents = db.Column(db.Integer, nullable=False, default=100) + default_buyin_cents = db.Column(db.Integer, nullable=False, default=0) + default_rebuy_cents = db.Column(db.Integer, nullable=False, default=0) __table_args__ = ( db.CheckConstraint( diff --git a/boker/routes/leagues.py b/boker/routes/leagues.py index ad73fb9..dcf40fd 100644 --- a/boker/routes/leagues.py +++ b/boker/routes/leagues.py @@ -105,12 +105,65 @@ def session_ref_map(league_id: str) -> dict[str, str]: return {session_event_ref(session): session.id for session in list_sessions_for_league(league_id)} -@leagues_bp.get("/leagues") +@leagues_bp.route("/leagues", methods=["GET", "POST"]) @login_required def index(): if not db_ready(): flash("League database is not available.", "error") - return render_template("leagues_index.html", leagues=[]) + return render_template("leagues_index.html", leagues=[], form={}) + + def _parse_cents(key: str) -> int: + raw = request.form.get(key, "").strip() + try: + return max(0, int(round(float(raw) * 100))) if raw else 0 + except ValueError: + return 0 + + form = { + "name": request.form.get("name", "").strip(), + "description": request.form.get("description", "").strip(), + "visibility": request.form.get("visibility", "private"), + "default_buyin_dollars": request.form.get("default_buyin_dollars", "").strip(), + "default_rebuy_dollars": request.form.get("default_rebuy_dollars", "").strip(), + "eligible_min_sessions": request.form.get("eligible_min_sessions", "").strip(), + "break_even_dollars": request.form.get("break_even_dollars", "").strip(), + } + + if request.method == "POST": + from boker.db_models import User + from boker.league_repositories import create_league, unique_league_slug + + owner = db.session.get(User, current_user_id()) + if owner is None: + flash("Login required.", "error") + return redirect(url_for("account.login")) + + if len(form["name"]) < 2: + flash("League name must be at least 2 characters.", "error") + else: + try: + eligible_min = int(form["eligible_min_sessions"]) if form["eligible_min_sessions"] else 3 + break_even_cents = round(float(form["break_even_dollars"]) * 100) if form["break_even_dollars"] else 100 + except (ValueError, TypeError): + flash("Sessions to rank and break-even threshold must be valid numbers.", "error") + eligible_min = None + + if eligible_min is not None: + slug = unique_league_slug(form["name"]) + league = create_league( + owner=owner, + name=form["name"], + slug=slug, + description=form["description"] or None, + ) + league.visibility = form["visibility"] if form["visibility"] in ("public", "private") else "private" + league.default_buyin_cents = _parse_cents("default_buyin_dollars") + league.default_rebuy_cents = _parse_cents("default_rebuy_dollars") + league.eligible_min_sessions = max(1, eligible_min) + league.break_even_cents = max(0, break_even_cents) + db.session.commit() + flash("League created.", "success") + return redirect(url_for("leagues.dashboard", **league_url_values(league))) from boker.league_repositories import list_leagues_for_user from boker.ledger_repositories import list_event_rows_for_league @@ -138,6 +191,7 @@ def index(): + session.total_current_due_to_house_cents for session in summaries ) + cash_paid_out_cents = sum(session.total_paid_out_cents for session in summaries) total_sessions += len(summaries) total_players += players_count total_events += len(events) @@ -155,9 +209,7 @@ def index(): "players_count": players_count, "sessions_count": len(summaries), "events_count": len(events), - "cash_paid_out_cents": sum( - session.total_paid_out_cents for session in summaries - ), + "cash_paid_out_cents": cash_paid_out_cents, "open_items_cents": open_items_cents, } ) @@ -168,51 +220,21 @@ def index(): "sessions_count": total_sessions, "events_count": total_events, "open_items_cents": total_open_items_cents, + "total_paid_out_cents": sum(item["cash_paid_out_cents"] for item in league_summaries), } return render_template( "leagues_index.html", leagues=league_summaries, page_summary=page_summary, session_label=session_label, + form=form, ) -@leagues_bp.route("/leagues/new", methods=["GET", "POST"]) +@leagues_bp.get("/leagues/new") @login_required def new(): - if not db_ready(): - flash("League database is not available.", "error") - return render_template("league_new.html", form={}) - - form = { - "name": request.form.get("name", "").strip(), - "description": request.form.get("description", "").strip(), - } - - if request.method == "POST": - from boker.db_models import User - from boker.league_repositories import create_league, unique_league_slug - - owner = db.session.get(User, current_user_id()) - if owner is None: - flash("Login required.", "error") - return redirect(url_for("account.login")) - - if len(form["name"]) < 2: - flash("League name must be at least 2 characters.", "error") - else: - slug = unique_league_slug(form["name"]) - league = create_league( - owner=owner, - name=form["name"], - slug=slug, - description=form["description"] or None, - ) - db.session.commit() - flash("League created.", "success") - return redirect(url_for("leagues.dashboard", **league_url_values(league))) - - return render_template("league_new.html", form=form) + return redirect(url_for("leagues.index")) @leagues_bp.get("/l/") @@ -272,6 +294,14 @@ def dashboard(league_ref: str): "has_sessions": bool(all_sessions), } + from boker.services import build_leaderboard + + leaderboard = build_leaderboard(all_sessions, league.break_even_cents) + live_sessions = [s for s in all_sessions if s.is_open] + live_session = live_sessions[0] if live_sessions else None + recent_sessions = sorted(all_sessions, key=session_sort_key, reverse=True)[:3] + house_balance_cents = total_paid_out - total_cash_in + return render_template( "league_dashboard.html", league=league, @@ -279,6 +309,12 @@ def dashboard(league_ref: str): can_manage=can_manage, is_owner=is_owner, cash_stats=cash_stats, + live_session=live_session, + recent_sessions=recent_sessions, + leaderboard_top=leaderboard[:3], + house_balance_cents=house_balance_cents, + session_label=session_label, + total_sessions=len(all_sessions), ) @@ -1092,6 +1128,8 @@ def session_detail(league_ref: str, session_id: str): is_owner=is_owner, session_label=session_label, seasons=seasons, + default_buyin_cents=league.default_buyin_cents, + default_rebuy_cents=league.default_rebuy_cents, ) @@ -1410,21 +1448,29 @@ def league_settings(league_ref: str): "visibility": league.visibility, "eligible_min_sessions": league.eligible_min_sessions, "break_even_dollars": f"{league.break_even_cents / 100:.2f}", + "default_buyin_dollars": f"{league.default_buyin_cents / 100:.2f}", + "default_rebuy_dollars": f"{league.default_rebuy_cents / 100:.2f}", } if request.method == "POST": raw_eligible = request.form.get("eligible_min_sessions", "3").strip() raw_break_even = request.form.get("break_even_dollars", "1.00").strip() + raw_default_buyin = request.form.get("default_buyin_dollars", "0").strip() + raw_default_rebuy = request.form.get("default_rebuy_dollars", "0").strip() form = { "name": request.form.get("name", "").strip(), "description": request.form.get("description", "").strip(), "visibility": request.form.get("visibility", "private").strip(), "eligible_min_sessions": raw_eligible, "break_even_dollars": raw_break_even, + "default_buyin_dollars": raw_default_buyin, + "default_rebuy_dollars": raw_default_rebuy, } try: eligible_min = int(raw_eligible) break_even_cents = round(float(raw_break_even) * 100) + default_buyin_cents = round(float(raw_default_buyin or "0") * 100) + default_rebuy_cents = round(float(raw_default_rebuy or "0") * 100) except (ValueError, TypeError): flash("Eligible sessions and break-even threshold must be valid numbers.", "error") else: @@ -1436,6 +1482,10 @@ def league_settings(league_ref: str): flash("Eligible minimum must be between 1 and 100.", "error") elif break_even_cents < 0 or break_even_cents > 10000: flash("Break-even threshold must be between $0.00 and $100.00.", "error") + elif default_buyin_cents < 0 or default_buyin_cents > 1000000: + flash("Default buy-in must be between $0.00 and $10,000.00.", "error") + elif default_rebuy_cents < 0 or default_rebuy_cents > 1000000: + flash("Default rebuy must be between $0.00 and $10,000.00.", "error") else: from boker.utils import slugify @@ -1445,6 +1495,8 @@ def league_settings(league_ref: str): league.visibility = form["visibility"] league.eligible_min_sessions = eligible_min league.break_even_cents = break_even_cents + league.default_buyin_cents = default_buyin_cents + league.default_rebuy_cents = default_rebuy_cents db.session.commit() flash("League settings saved.", "success") return redirect(url_for("leagues.league_settings", league_ref=league.url_ref)) diff --git a/migrations/versions/0006_league_default_buyin.py b/migrations/versions/0006_league_default_buyin.py new file mode 100644 index 0000000..1939388 --- /dev/null +++ b/migrations/versions/0006_league_default_buyin.py @@ -0,0 +1,43 @@ +"""add default_buyin_cents to leagues + +Revision ID: 0006_league_default_buyin +Revises: 0005_site_admin_accounts +Create Date: 2026-08-21 +""" +from __future__ import annotations + +from alembic import context, op +import sqlalchemy as sa + + +revision = "0006_league_default_buyin" +down_revision = "0005_site_admin_accounts" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + if context.is_offline_mode(): + op.add_column( + "leagues", + sa.Column("default_buyin_cents", sa.Integer(), nullable=False, server_default="0"), + ) + return + + columns = {column["name"] for column in sa.inspect(op.get_bind()).get_columns("leagues")} + if "default_buyin_cents" not in columns: + with op.batch_alter_table("leagues") as batch_op: + batch_op.add_column(sa.Column( + "default_buyin_cents", sa.Integer(), nullable=False, server_default="0" + )) + + +def downgrade() -> None: + if context.is_offline_mode(): + op.drop_column("leagues", "default_buyin_cents") + return + + columns = {column["name"] for column in sa.inspect(op.get_bind()).get_columns("leagues")} + if "default_buyin_cents" in columns: + with op.batch_alter_table("leagues") as batch_op: + batch_op.drop_column("default_buyin_cents") diff --git a/migrations/versions/0007_league_default_rebuy.py b/migrations/versions/0007_league_default_rebuy.py new file mode 100644 index 0000000..28ace04 --- /dev/null +++ b/migrations/versions/0007_league_default_rebuy.py @@ -0,0 +1,43 @@ +"""add default_rebuy_cents to leagues + +Revision ID: 0007_league_default_rebuy +Revises: 0006_league_default_buyin +Create Date: 2026-08-21 +""" +from __future__ import annotations + +from alembic import context, op +import sqlalchemy as sa + + +revision = "0007_league_default_rebuy" +down_revision = "0006_league_default_buyin" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + if context.is_offline_mode(): + op.add_column( + "leagues", + sa.Column("default_rebuy_cents", sa.Integer(), nullable=False, server_default="0"), + ) + return + + columns = {column["name"] for column in sa.inspect(op.get_bind()).get_columns("leagues")} + if "default_rebuy_cents" not in columns: + with op.batch_alter_table("leagues") as batch_op: + batch_op.add_column(sa.Column( + "default_rebuy_cents", sa.Integer(), nullable=False, server_default="0" + )) + + +def downgrade() -> None: + if context.is_offline_mode(): + op.drop_column("leagues", "default_rebuy_cents") + return + + columns = {column["name"] for column in sa.inspect(op.get_bind()).get_columns("leagues")} + if "default_rebuy_cents" in columns: + with op.batch_alter_table("leagues") as batch_op: + batch_op.drop_column("default_rebuy_cents") diff --git a/static/css/style.css b/static/css/style.css index f49bd10..c39dcfc 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -37,9 +37,9 @@ h1, h2, h3, h4 { margin: 0; } ================================================================ */ :root { --font-ui: 'Inter', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; - --font-display: var(--font-ui); - --font-mono: ui-monospace, "SFMono-Regular", "Cascadia Mono", "Roboto Mono", "Liberation Mono", monospace; - --font-money: var(--font-ui); + --font-display: 'Archivo', 'Inter', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + --font-mono: 'JetBrains Mono', ui-monospace, "SFMono-Regular", "Cascadia Mono", "Roboto Mono", "Liberation Mono", monospace; + --font-money: var(--font-mono); } /* ================================================================ @@ -97,7 +97,7 @@ h1, h2, h3, h4 { margin: 0; } transition: color .15s, background .15s; } .subnav__link:hover { color: var(--text); background: var(--panel-hover); } -.subnav__link.is-active { color: var(--accent); font-weight: 600; } +.subnav__link.is-active { color: var(--text-strong); font-weight: 600; border-bottom: 2px solid var(--accent); } /* ================================================================ APP SHELL + SIDEBAR @@ -291,7 +291,7 @@ h1, h2, h3, h4 { margin: 0; } margin-bottom: 6px; } .int-hero-card__icon--users { background: var(--accent-chip); border: 1px solid var(--accent-chip-bd); color: var(--accent); } -.int-hero-card__icon--leagues { background: rgba(111,192,147,.12); border: 1px solid rgba(111,192,147,.25); color: var(--pos); } +.int-hero-card__icon--leagues { background: rgba(103,185,135,.12); border: 1px solid rgba(103,185,135,.25); color: var(--pos); } .int-hero-card__icon--sessions { background: var(--warn-tint); border: 1px solid var(--warn-tint-bd); color: var(--warn); } .int-hero-card__icon--health { background: rgba(120,180,240,.1); border: 1px solid rgba(120,180,240,.22); color: #78b4f0; } .int-hero-card__num { @@ -428,7 +428,7 @@ h1, h2, h3, h4 { margin: 0; } ================================================================ */ .topbar { position: sticky; top: 0; z-index: 50; - background: rgba(10,10,13,.94); + background: rgba(20,23,27,.96); backdrop-filter: blur(10px); border-bottom: 1px solid var(--border); } @@ -450,9 +450,8 @@ h1, h2, h3, h4 { margin: 0; } } .brand__mark { width: 30px; height: 30px; - border-radius: 7px; + border-radius: 5px; background: var(--accent); - box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); position: relative; flex: none; } @@ -518,15 +517,29 @@ h1, h2, h3, h4 { margin: 0; } .nav-is-open .nav-toggle span:nth-child(2) { opacity: 0; transform: scaleX(.2); } .nav-is-open .nav-toggle span:nth-child(3) { transform: rotate(-45deg) scaleX(1.04); } .navlink { + position: relative; font-size: 13.5px; font-weight: 600; padding: 7px 12px; border-radius: var(--r-pill); color: var(--muted); - transition: color 140ms, background 140ms; + transition: color 140ms; +} +.navlink::after { + content: ""; + position: absolute; + left: 12px; + right: 12px; + bottom: -1px; + height: 2px; + background: var(--accent); + transform: scaleX(0); + transform-origin: left center; + transition: transform 160ms ease; } .navlink:hover { color: var(--text-strong); } -.navlink.is-active { color: var(--text-strong); background: var(--field-alt); } +.navlink.is-active { color: var(--text-strong); } +.navlink.is-active::after { transform: scaleX(1); } .navlink--mobile-auth { display: none; } .topbar__spacer { flex: 1; } .topbar__season { @@ -550,6 +563,7 @@ h1, h2, h3, h4 { margin: 0; } } .page--public { max-width: var(--w-public); } .page--session { max-width: var(--w-session); } +.page--leagues { padding-left: clamp(12px, 2vw, 24px); padding-right: clamp(12px, 2vw, 24px); } .page--admin { max-width: var(--w-admin); } @media (min-width: 1280px) { .page--admin, @@ -792,22 +806,27 @@ h3 { PANEL / CARD ================================================================ */ .panel { - background: var(--surface); - border: var(--glass-border); - border-radius: var(--r-lg); - box-shadow: var(--shadow-sm); - overflow: hidden; + background: transparent; + border: none; + border-top: 1px solid var(--border); + border-radius: 0; + overflow: visible; min-width: 0; - transition: border-color 140ms, box-shadow 140ms; +} +.panel.form-card { + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--r-md); + overflow: hidden; } .panel__head { - padding: 16px 22px; - border-bottom: 1px solid var(--field-alt); + padding: 16px 20px; + border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: 12px; - background: var(--surface-head); + background: var(--surface); } .panel__title { font-family: var(--font-display); @@ -818,6 +837,7 @@ h3 { color: var(--text-strong); } .panel__tag { font-family: var(--font-mono); font-size: 11px; color: var(--faintest); } +.panel__note { display: block; margin-top: 4px; font-size: 12px; color: var(--muted); } .panel__body { padding: 20px; } /* panel-header — old utility kept for admin forms */ @@ -837,9 +857,8 @@ h3 { .stat { padding: 18px 20px; background: var(--surface); - border: var(--glass-border); + border: 1px solid var(--border); border-radius: var(--r-md); - box-shadow: var(--shadow-sm); position: relative; overflow: hidden; } @@ -870,15 +889,28 @@ h3 { .player-stat-grid { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); - gap: var(--s3); + gap: 1px; + background: var(--border); + border: 1px solid var(--border); + border-radius: var(--r-md); + overflow: hidden; } .player-stat-grid .stat { min-width: 0; + border: none; + border-radius: 0; + background: var(--surface); } .player-stat-grid .stat__val { font-size: clamp(19px, 1.7vw, 24px); word-break: keep-all; } +@media (max-width: 1100px) { + .player-stat-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } +} +@media (max-width: 560px) { + .player-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } +} .stat-pair { display: flex; flex-wrap: wrap; @@ -893,15 +925,7 @@ h3 { line-height: 1; white-space: nowrap; } -.stat--rail { position: relative; padding-left: 20px; background: var(--surface); } -.stat--rail::before { - content: ""; - position: absolute; - left: 0; top: 0; bottom: 0; - width: 3px; - background: var(--rail, var(--accent)); - border-radius: 0 2px 2px 0; -} +.stat--rail { background: var(--surface); } /* hero stat row (small inline tiles) */ .stat-row-inline { @@ -924,11 +948,10 @@ h3 { .toolbar__left { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; } .toolbar__right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } .toolbar__hint { - font-size: 12.5px; - color: var(--muted); - max-width: 42ch; + font-size: 12px; + color: var(--faintest); line-height: 1.4; - margin: 0; + margin: -4px 0 16px; } .sortnote { font-family: var(--font-mono); font-size: 11.5px; color: var(--faintest); } .sortnote b { color: var(--text-2); font-weight: 500; } @@ -1023,6 +1046,48 @@ h3 { } .form-card textarea { resize: vertical; min-height: 92px; } .form-card input::placeholder, .form-card textarea::placeholder { color: var(--faintest-2); } + +/* --- Compact ledger entry form --- */ +.ledger-form { padding: 16px; gap: 0; } +.ledger-form__head { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 14px; +} +.ledger-form__status { + font: 600 10px/1 var(--font-mono); + letter-spacing: .08em; + text-transform: uppercase; + padding: 3px 8px; + border-radius: var(--r-sm); +} +.ledger-form__status--open { color: var(--pos); background: rgba(103,185,135,.08); border: 1px solid rgba(103,185,135,.22); } +.ledger-form__status--closed { color: var(--faint); background: var(--surface-raised); border: 1px solid var(--border-strong); } +.ledger-form fieldset { gap: 10px; } +.ledger-form .form-card input, +.ledger-form .form-card select, +.ledger-form .form-card textarea { padding: 8px 10px; font-size: 13.5px; } +.ledger-form .field-label { + font-family: var(--font-mono); + font-size: 10px; + letter-spacing: .10em; + color: var(--faintest); + text-transform: uppercase; + margin-bottom: 6px; +} +.ledger-form .form-card textarea { min-height: 54px; } +.ledger-form__row2 { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + align-items: start; +} +.ledger-form__submit { + width: 100%; + margin-top: 4px; + justify-content: center; +} .session-locked-banner { display: flex; flex-direction: column; @@ -1036,6 +1101,150 @@ h3 { } .session-locked-banner strong { color: var(--warn); } .session-locked-banner span { color: var(--text-muted); } + +/* --- Player picker (custom searchable dropdown) --- */ +.player-picker { position: relative; } +.player-picker__input-wrap { + position: relative; + display: flex; + align-items: center; +} +.player-picker__search { + width: 100%; + padding-right: 28px; +} +.player-picker__chevron { + position: absolute; + right: 10px; + color: var(--muted); + pointer-events: none; + flex-shrink: 0; +} +.player-picker__dropdown { + position: absolute; + top: calc(100% + 4px); + left: 0; right: 0; + z-index: 120; + background: var(--surface-raised); + border: 1px solid var(--border-strong); + border-radius: var(--r-md); + overflow-y: auto; + max-height: 220px; + box-shadow: 0 4px 16px rgba(0,0,0,.36); +} +.player-picker__opt { + display: block; + width: 100%; + padding: 9px 14px; + text-align: left; + background: none; + border: none; + border-bottom: 1px solid var(--border); + color: var(--text-strong); + font: 500 13.5px/1 var(--font-ui); + cursor: pointer; + transition: background .1s; +} +.player-picker__opt:last-child { border-bottom: none; } +.player-picker__opt:hover { background: var(--field-alt); color: var(--text-strong); } + +/* --- Amount field + default button --- */ +.field-label { + display: block; + font: 600 12px/1 var(--font-ui); + color: var(--text-2); + text-transform: uppercase; + letter-spacing: .04em; + margin-bottom: 6px; +} +.ledger-form__ta-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + align-items: stretch; +} +.ledger-form__inputs { + display: flex; + flex-direction: column; + gap: 10px; +} +.amount-quickset { + display: flex; + flex-direction: column; + gap: 6px; +} +.amount-quickset__presets { + display: flex; + gap: 6px; + flex: 1; +} +.amount-quickset__btn { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 5px; + padding: 0 8px; + flex: 1; + background: var(--surface-raised); + border: 1px solid var(--border-strong); + border-radius: var(--r-sm); + cursor: pointer; + transition: background .1s, border-color .1s; +} +.amount-quickset__btn:hover { border-color: var(--accent); background: var(--accent-chip); } +.amount-quickset__btn.is-active { background: var(--accent-chip); border-color: var(--accent); } +.amount-quickset__lbl { + font: 600 11px/1 var(--font-ui); + text-transform: uppercase; + letter-spacing: .06em; + color: var(--text-2); +} +.amount-quickset__btn.is-active .amount-quickset__lbl { color: var(--accent); } +.amount-quickset__val { + font: 700 17px/1 var(--font-mono); + color: var(--text-strong); + font-variant-numeric: tabular-nums; +} +.amount-quickset__btn.is-active .amount-quickset__val { color: var(--accent); } +.amount-quickset__mults { + display: flex; + gap: 6px; +} +.amount-quickpick__btn { + flex: 1; + padding: 8px 0; + background: var(--surface-raised); + border: 1px solid var(--border-strong); + border-radius: var(--r-sm); + color: var(--muted); + font: 700 14px/1 var(--font-mono); + cursor: pointer; + transition: border-color .1s, background .1s, color .1s; +} +.amount-quickpick__btn:hover { border-color: var(--border-hi); color: var(--text-2); } +.amount-quickpick__btn.is-active { background: var(--accent-chip); border-color: var(--accent); color: var(--accent); } +@media (max-width: 540px) { + .ledger-form__ta-row { grid-template-columns: 1fr; } + .amount-quickset { flex-direction: row; flex-wrap: wrap; } + .amount-quickset__presets { flex: 1; } + .amount-quickset__btn { min-height: 64px; } + .amount-quickset__mults { border-left: 1px solid var(--border-strong); padding-left: 6px; } +} + +/* --- Ledger tally chips --- */ +.ledger-tally { + font: 600 11px/1 var(--font-mono); + padding: 3px 8px; + border-radius: var(--r-sm); + letter-spacing: .04em; + text-transform: uppercase; + white-space: nowrap; +} +.ledger-tally--playing { background: rgba(103,185,135,.08); color: var(--pos); border: 1px solid rgba(103,185,135,.25); } +.ledger-tally--settled { background: var(--accent-chip); color: var(--accent); border: 1px solid var(--accent-chip-bd); } +.ledger-tally--owes { background: rgba(212,107,114,.1); color: var(--neg); border: 1px solid rgba(212,107,114,.25); } +.ledger-tally--owed { background: rgba(197,164,90,.1); color: var(--warn); border: 1px solid rgba(197,164,90,.25); } fieldset[disabled] input, fieldset[disabled] select, fieldset[disabled] textarea, @@ -1115,7 +1324,7 @@ fieldset[disabled] button { color: var(--text-body); } .tbl tbody tr { cursor: pointer; transition: background 80ms; } -.tbl tbody tr:hover { background: rgba(155,140,240,.04); } +.tbl tbody tr:hover { background: rgba(129,119,183,.04); } .tbl .num-net { font-weight: 600; font-size: 15px; } .tbl .num-pos { color: var(--pos); } .tbl .num-neg { color: var(--neg); } @@ -1209,7 +1418,7 @@ th { border-bottom: 1px solid var(--border); } tbody tr { transition: background 80ms; } -tbody tr:hover { background: rgba(155,140,240,.04); } +tbody tr:hover { background: rgba(129,119,183,.04); } tbody tr:not(:last-child) td { border-bottom: 1px solid var(--divider); } td { font-size: 13.5px; color: var(--text-body); } td a { font-weight: 600; color: var(--text-strong); } @@ -1230,6 +1439,7 @@ td a:hover { color: var(--accent); } white-space: nowrap; } .badge--paid { color: var(--pos); background: var(--pos-tint); box-shadow: inset 0 0 0 1px var(--pos-tint-bd); } +.badge--playing { color: var(--pos); background: rgba(103,185,135,.07); box-shadow: inset 0 0 0 1px rgba(103,185,135,.22); } .badge--settled { color: var(--rolled); background: var(--surface-raised); box-shadow: inset 0 0 0 1px var(--border); } .badge--partial { color: var(--warn); background: var(--warn-tint); box-shadow: inset 0 0 0 1px var(--warn-tint-bd); } .badge--unpaid { color: var(--neg); background: var(--neg-tint); box-shadow: inset 0 0 0 1px var(--neg-tint-bd); } @@ -1300,7 +1510,7 @@ td a:hover { color: var(--accent); } position: relative; height: clamp(220px, 30vw, 300px); } -.chart-frame--tall { height: clamp(260px, 36vw, 340px); } +.chart-frame--tall { height: clamp(320px, 42vw, 420px); } .chart-frame canvas { width: 100% !important; height: 100% !important; } .session-net-bars { @@ -1575,12 +1785,18 @@ td a:hover { color: var(--accent); } white-space: nowrap; transition: background 120ms, border-color 120ms, color 120ms, opacity 120ms; } -.btn--primary { background: var(--accent); color: var(--accent-ink); box-shadow: none; font-weight: 700; } -.btn--primary:hover { opacity: .9; } -.btn--ghost { background: var(--field); color: var(--text-2); border: 1px solid var(--border-strong); font-weight: 600; } -.btn--ghost:hover { border-color: var(--border-hi); color: var(--text-strong); } -.btn--outline { background: var(--accent-tint); color: var(--accent); border: 1px solid var(--accent-chip-bd); } -.btn--outline:hover { background: var(--accent-chip); } +.btn--primary { + background: var(--accent); + color: var(--accent-ink); + font-weight: 700; + box-shadow: 0 1px 0 rgba(255,255,255,.14) inset, 0 6px 18px -8px var(--accent-a30); +} +.btn--primary:hover { background: color-mix(in srgb, var(--accent) 88%, white); } +.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +.btn--ghost { background: transparent; color: var(--text-2); border: 1px solid var(--border-strong); font-weight: 600; } +.btn--ghost:hover { border-color: var(--border-hi); color: var(--text-strong); background: var(--surface-raised); } +.btn--outline { background: transparent; color: var(--accent); border: 1px solid var(--accent-chip-bd); } +.btn--outline:hover { background: var(--accent-tint); border-color: var(--accent); } .btn--warning { background: var(--warn-tint); color: var(--warn); @@ -1655,16 +1871,18 @@ td a:hover { color: var(--accent); } .cards-2 { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); } .leaderboard-hero-stats { display: flex; - gap: 12px; - flex-wrap: wrap; - align-self: center; - justify-content: flex-end; + gap: 1px; + background: var(--border); + border: 1px solid var(--border); + border-radius: var(--r-md); + overflow: hidden; + margin-bottom: 24px; } .leaderboard-hero-stats .stat { - min-width: 132px; -} -.leaderboard-hero-stats .stat:last-child { - min-width: 168px; + border: none; + border-radius: 0; + flex: 1; + min-width: 0; } .split { display: flex; flex-wrap: wrap; gap: var(--s4); align-items: flex-start; } .split > .col-main { flex: 2; min-width: 360px; } @@ -1816,9 +2034,13 @@ td a:hover { color: var(--accent); } /* Cash position strip */ .cash-strip { display: grid; - gap: var(--s3); - grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); - margin-bottom: 28px; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 1px; + background: var(--border); + border: 1px solid var(--border); + border-radius: var(--r-md); + overflow: hidden; + margin-bottom: 24px; } /* Live indicator dot */ @@ -2174,7 +2396,6 @@ select.control { cursor: pointer; } border-style: solid; border-color: var(--accent); color: var(--accent-ink); - box-shadow: 0 4px 16px var(--accent-a30); } .btn-newsession--primary:hover { color: var(--accent-ink); opacity: .88; } .prune-session-form { @@ -2268,7 +2489,7 @@ select.control { cursor: pointer; } .form-shell { display: grid; justify-content: center; padding-top: 48px; } .form-shell.narrow { grid-template-columns: minmax(320px, 440px); } .form-shell .panel { - box-shadow: 0 24px 64px rgba(0,0,0,.28), 0 0 0 1px var(--border-strong); + box-shadow: none; } /* Account / league shell */ @@ -2277,26 +2498,25 @@ select.control { cursor: pointer; } grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; } -.league-action-grid, -.league-manage-grid { +.league-action-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; } .league-manage-grid { - align-items: start; + display: flex; + flex-direction: column; + gap: 0; } .league-card { display: grid; gap: 8px; padding: 18px; color: inherit; - transition: border-color 160ms, transform 160ms, box-shadow 160ms; + transition: border-color 160ms; } .league-card:hover { - border-color: var(--accent); - transform: translateY(-2px); - box-shadow: 0 6px 20px rgba(0,0,0,.18), 0 0 0 1px color-mix(in srgb, var(--accent) 20%, transparent); + border-color: var(--border-strong); } .league-card--disabled { opacity: .72; @@ -2365,8 +2585,7 @@ select.control { cursor: pointer; } color: var(--accent); } .league-row:hover { - box-shadow: var(--shadow-lg), 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent); - transform: translateY(-2px); + box-shadow: none; } .league-row__desc { margin: 0; @@ -2523,44 +2742,95 @@ select.control { cursor: pointer; } .player-row__actions form { margin: 0; } +.player-toolbar { + display: flex; + align-items: center; + gap: 12px; + flex-wrap: wrap; + justify-content: flex-end; +} +.player-search { + width: 180px; + min-width: 160px; + padding: 7px 10px; + border: 1px solid var(--border); + border-radius: var(--r-sm); + background: var(--field); + color: var(--text); + font: 400 13px/1 var(--font-ui); + outline: none; + transition: border-color .15s, box-shadow .15s; +} +.player-search:focus { + border-color: var(--accent-chip-bd); + box-shadow: 0 0 0 3px var(--accent-a22); +} +.player-view-toggle { + display: flex; + align-items: center; + gap: 0; + overflow: hidden; + border: 1px solid var(--border); + border-radius: var(--r-sm); + background: var(--surface-sunk); +} +.player-view-toggle__btn { + min-width: 58px; + min-height: 30px; + padding: 0 12px; + border: 0; + border-right: 1px solid var(--border); + background: transparent; + color: var(--text-muted); + font: 700 11px/1 var(--font-ui); + letter-spacing: .05em; + text-transform: uppercase; + transition: background .12s, color .12s; +} +.player-view-toggle__btn:last-child { border-right: 0; } +.player-view-toggle__btn:hover { color: var(--text-strong); } +.player-view-toggle__btn.is-on { + background: var(--accent); + color: var(--accent-ink); +} /* Player card grid */ .player-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); + grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; padding: 16px; } .player-card { - border: var(--glass-border); + background: var(--surface); + border: 1px solid var(--border); border-radius: var(--r-md); - padding: 18px; + padding: 20px; display: flex; flex-direction: column; - gap: 12px; + gap: 14px; text-decoration: none; - box-shadow: var(--shadow-sm); - transition: border-color 0.18s, box-shadow 0.18s; + transition: background .18s, border-color .18s; } .player-card:hover { - border-color: color-mix(in srgb, var(--accent) 40%, transparent); - box-shadow: var(--shadow-lg), 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent); + background: var(--surface-raised); + border-color: var(--border-strong); } .player-card--archived { opacity: 0.5; } .player-card__head { display: flex; align-items: center; - gap: 10px; + gap: 12px; } .player-avatar { - width: 40px; - height: 40px; + width: 46px; + height: 46px; border-radius: 50%; background: var(--surface-2); color: var(--muted); display: flex; align-items: center; justify-content: center; - font-size: 13px; + font-size: 14px; font-weight: 700; flex-shrink: 0; letter-spacing: 0.02em; @@ -2569,6 +2839,7 @@ select.control { cursor: pointer; } .player-avatar--neg { background: color-mix(in srgb, var(--neg) 18%, transparent); color: var(--neg); } .player-card__name-block { flex: 1; min-width: 0; } .player-card__name { + font-size: 15px; font-weight: 600; color: var(--text); text-decoration: none; @@ -2578,21 +2849,56 @@ select.control { cursor: pointer; } text-overflow: ellipsis; } .player-card__name:hover { color: var(--accent); } -.player-card__sub { font-size: 12px; color: var(--muted); display: block; margin-top: 1px; } +.player-card__sub { font-size: 12px; color: var(--muted); display: block; margin-top: 2px; } .player-card__stats { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px; border-top: 1px solid var(--border); - padding-top: 12px; + padding-top: 14px; } .player-card__stat { display: flex; flex-direction: column; - gap: 2px; + gap: 3px; } .player-card__stat .kicker { font-size: 9px; } -.player-card__stat-val { font-size: 13px; font-weight: 600; color: var(--text); } +.player-card__stat-val { font-size: 14px; font-weight: 600; color: var(--text); } +.player-grid__empty { display: none; padding: 24px 16px; color: var(--muted); font-size: 14px; } +.player-grid[data-view="list"] { + display: flex; + flex-direction: column; + gap: 0; + padding: 0; +} +.player-grid[data-view="list"] .player-card { + min-height: 72px; + padding: 14px 20px; + border-width: 0 0 1px; + border-radius: 0; + display: grid; + grid-template-columns: minmax(220px, 1.25fr) minmax(360px, 1fr); + align-items: center; + gap: 18px; +} +.player-grid[data-view="list"] .player-card:first-child { + border-top: 1px solid var(--border-strong); +} +.player-grid[data-view="list"] .player-card:hover { + background: color-mix(in srgb, var(--accent) 5%, var(--surface)); +} +.player-grid[data-view="list"] .player-card__stats { + padding-top: 0; + border-top: 0; + gap: 14px; +} +.player-grid[data-view="list"] .player-card__stat { + min-width: 0; +} +.player-grid[data-view="list"] .player-card__stat-val { + font-variant-numeric: tabular-nums; + white-space: nowrap; +} /* Danger zone row (description left, action button right) */ .danger-row { display: flex; @@ -2716,6 +3022,7 @@ select.control { cursor: pointer; } .status-pill { display: inline-flex; align-items: center; + justify-content: center; min-height: 26px; padding: 4px 9px; border-radius: var(--r-pill); @@ -2723,6 +3030,7 @@ select.control { cursor: pointer; } color: var(--muted); font: 11px var(--font-mono); text-transform: uppercase; + letter-spacing: .05em; } .status-pill--active { border-color: var(--pos-tint-bd); @@ -2785,7 +3093,10 @@ select.control { cursor: pointer; } } .session-row__stat { display: inline-flex; align-items: center; gap: 4px; } .session-row__actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; } -.session-row__actions form { margin: 0; } +.session-row__actions .status-pill { width: 70px; flex-shrink: 0; } +.session-row__actions form { margin: 0; width: 80px; flex-shrink: 0; } +.session-row__actions form .btn { width: 100%; justify-content: center; } +.session-row__btn { width: 80px; flex-shrink: 0; justify-content: center; } @media (max-width: 640px) { .session-row { @@ -2861,56 +3172,54 @@ select.control { cursor: pointer; } } } -/* Session detail — full-width player ledger rows */ +/* Session detail — player ledger rows */ .player-ledger-list { display: flex; flex-direction: column; - max-height: 480px; - overflow-y: auto; - border-radius: 0 0 var(--r-lg) var(--r-lg); + gap: 1px; + background: var(--border); } .player-ledger-row { - padding: 14px 20px; - border-bottom: 1px solid var(--border); - border-left: 3px solid var(--border-strong); - display: flex; - flex-direction: column; - gap: 10px; -} -.player-ledger-row:last-child { border-bottom: none; } -.player-ledger-row--pos { border-left-color: var(--pos); } -.player-ledger-row--neg { border-left-color: var(--neg); } -.player-ledger-row__header { display: flex; align-items: center; - justify-content: space-between; - gap: 12px; -} -.player-ledger-row__name { font-size: 15px; font-weight: 700; color: var(--text-strong); } -.player-ledger-row__fields { - display: grid; - grid-template-columns: repeat(4, 1fr); - border: 1px solid var(--border); - border-radius: var(--r-sm); - overflow: hidden; -} -.player-ledger-row__fields--secondary { - grid-template-columns: repeat(3, 1fr); - background: var(--surface-sunk); -} -.player-ledger-row__field { - padding: 8px 12px; - display: flex; - flex-direction: column; - gap: 3px; - border-right: 1px solid var(--border); + gap: 16px; + padding: 14px 20px; background: var(--surface); } -.player-ledger-row__fields--secondary .player-ledger-row__field { - background: var(--surface-sunk); +.player-ledger-row__who { + display: flex; + align-items: center; + gap: 8px; + min-width: 160px; + flex-shrink: 0; +} +.player-ledger-row__name { + font-size: 15px; + font-weight: 700; + color: var(--text-strong); + white-space: nowrap; +} +.player-ledger-row__stats { + display: flex; + gap: 24px; + flex: 1; + flex-wrap: wrap; +} +.player-ledger-row__stat { + display: flex; + flex-direction: column; + gap: 2px; + min-width: 56px; +} +.player-ledger-row__stat--net { min-width: 64px; } +.player-ledger-row__actions { + display: flex; + align-items: center; + gap: 6px; + flex-shrink: 0; + border-left: 1px solid var(--border); + padding-left: 16px; } -.player-ledger-row__field:last-child { border-right: none; } -.player-ledger-row__field--net { background: var(--surface-subtle); } .player-ledger-row__lbl { font-size: 9.5px; text-transform: uppercase; @@ -2925,10 +3234,11 @@ select.control { cursor: pointer; } color: var(--text); font-variant-numeric: tabular-nums; } -@media (max-width: 600px) { - .player-ledger-row__fields { grid-template-columns: repeat(2, 1fr); } - .player-ledger-row__field { border-bottom: 1px solid var(--border); } - .player-ledger-row__fields--secondary { grid-template-columns: repeat(2, 1fr); } +@media (max-width: 700px) { + .player-ledger-row { flex-wrap: wrap; gap: 10px; } + .player-ledger-row__who { min-width: 100%; } + .player-ledger-row__stats { gap: 16px; } + .player-ledger-row__actions { border-left: none; padding-left: 0; } } /* Modal */ @@ -3009,10 +3319,34 @@ select.control { cursor: pointer; } padding-bottom: 18px; } .panel { - border-radius: 12px; + border-radius: 0; + } + .panel.form-card { + border-radius: var(--r-md); } .panel__head { - padding: 14px 14px; + padding: 14px 16px; + } + .player-toolbar { + width: 100%; + justify-content: space-between; + gap: 8px; + } + .player-search { + flex: 1 1 100%; + width: 100%; + } + .player-grid { + grid-template-columns: 1fr; + padding: 12px 0; + } + .player-grid[data-view="list"] .player-card { + grid-template-columns: 1fr; + gap: 12px; + padding: 14px 16px; + } + .player-grid[data-view="list"] .player-card__stats { + grid-template-columns: repeat(3, minmax(0, 1fr)); } .panel__body, .form-card, @@ -3042,7 +3376,7 @@ select.control { cursor: pointer; } .form-shell.narrow { grid-template-columns: minmax(0, 480px); } - .cash-strip { grid-template-columns: 1fr 1fr; } + .cash-strip { grid-template-columns: 1fr 1fr; border-radius: var(--r-sm); } .debt-action-grid { grid-template-columns: 1fr; } .snapshot-grid { grid-template-columns: 1fr; } .recon-metric-grid { grid-template-columns: 1fr; } @@ -3131,7 +3465,7 @@ select.control { cursor: pointer; } } @media (max-width: 440px) { - .cash-strip { grid-template-columns: 1fr; } + .cash-strip { grid-template-columns: 1fr 1fr; } } /* ================================================================ @@ -3290,9 +3624,10 @@ select.control { cursor: pointer; } margin-bottom: 6px; } .page-header__title { - font-size: clamp(20px, 2.4vw, 26px); - font-weight: 700; - letter-spacing: -.025em; + font-family: var(--font-display); + font-size: clamp(21px, 2.4vw, 27px); + font-weight: 800; + letter-spacing: -.02em; color: var(--text-strong); margin: 0 0 3px; } @@ -3402,10 +3737,11 @@ select.control { cursor: pointer; } display: flex; align-items: center; gap: 14px; - padding: 12px 18px; + padding: 10px 16px; background: var(--pos-tint); border: 1px solid var(--pos-tint-bd); - border-radius: var(--r-lg); + border-left: 2px solid var(--pos); + border-radius: var(--r-sm); margin-bottom: 16px; flex-wrap: wrap; } @@ -3553,14 +3889,6 @@ select.control { cursor: pointer; } z-index: -1; pointer-events: none; } -.l-bg::after { - content: ""; - position: absolute; - inset: 0; - background: - radial-gradient(ellipse 75% 60% at 12% 12%, rgba(155,140,240,.07) 0%, transparent 55%), - radial-gradient(ellipse 55% 45% at 88% 88%, rgba(111,192,147,.04) 0%, transparent 52%); -} .l-hero { padding: clamp(72px, 10vw, 128px) 0 clamp(44px, 6vw, 68px); @@ -3608,9 +3936,8 @@ select.control { cursor: pointer; } margin-top: 40px; padding: 18px 24px; background: var(--surface); - border: var(--glass-border); - border-radius: var(--r-lg); - box-shadow: var(--shadow-sm); + border: 1px solid var(--border); + border-radius: var(--r-md); } .l-stat-strip__item { display: flex; @@ -3650,14 +3977,12 @@ select.control { cursor: pointer; } } .l-preview__panel { background: var(--surface); - border: var(--glass-border); - border-radius: var(--r-lg); + border: 1px solid var(--border); + border-radius: var(--r-md); overflow: hidden; - box-shadow: var(--shadow-md); } .l-preview__panel--featured { border-color: var(--accent-chip-bd); - box-shadow: var(--shadow-xl), 0 0 0 1px var(--accent-chip-bd); } .l-preview__head { display: flex; @@ -3826,18 +4151,15 @@ select.control { cursor: pointer; } flex-direction: column; gap: 14px; padding: 20px 22px; - border: var(--glass-border); - border-radius: var(--r-lg); + border: 1px solid var(--border); + border-radius: var(--r-md); background: var(--surface); - box-shadow: var(--shadow-sm); text-decoration: none; color: inherit; - transition: border-color 0.18s, box-shadow 0.18s, transform 0.18s; + transition: border-color 0.18s; } .explore-card:hover { - border-color: var(--accent); - box-shadow: 0 4px 24px color-mix(in srgb, var(--accent) 12%, transparent), 0 0 0 1px color-mix(in srgb, var(--accent) 20%, transparent); - transform: translateY(-2px); + border-color: var(--border-strong); } .explore-card__head { display: flex; flex-direction: column; gap: 4px; } .explore-card__name { font-size: 16px; font-weight: 700; color: var(--text-strong); margin: 0; } @@ -4196,12 +4518,12 @@ select.control { cursor: pointer; } justify-self: start; padding: 3px 8px; border: 1px solid var(--border); - border-radius: 999px; + border-radius: var(--r-sm); font: 700 10px/1 var(--font-ui); letter-spacing: .04em; text-transform: uppercase; color: var(--muted); - background: var(--surface-subtle); + background: var(--surface-raised); } .member-role--owner { color: var(--accent); @@ -4281,6 +4603,7 @@ select.control { cursor: pointer; } .page--landing { padding: 0; max-width: none; + background: var(--bg); } .page--landing .flash-stack { max-width: var(--w-public); @@ -4311,11 +4634,7 @@ select.control { cursor: pointer; } padding: clamp(48px, 5vw, 68px) clamp(24px, 5vw, 80px); position: relative; overflow: hidden; - background: - radial-gradient(ellipse 85% 62% at 50% 108%, rgba(155,140,240,.105) 0%, rgba(155,140,240,.035) 48%, transparent 72%), - radial-gradient(ellipse 50% 40% at 88% 16%, rgba(111,192,147,.035) 0%, transparent 58%), - linear-gradient(180deg, color-mix(in srgb, var(--accent) 7%, var(--bg)) 0%, var(--bg) 82%), - var(--bg); + background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 4%, var(--bg)) 0%, var(--bg) 70%); } .lp-hero::before { content: "♠"; @@ -4351,23 +4670,20 @@ select.control { cursor: pointer; } display: inline-flex; align-items: center; gap: 7px; - padding: 5px 14px; - border-radius: var(--r-pill); - background: var(--surface-raised); - border: 1px solid var(--border); color: var(--muted); font: 600 10.5px var(--font-mono); - letter-spacing: .10em; + letter-spacing: .12em; text-transform: uppercase; margin-bottom: 20px; align-self: flex-start; } .lp-eyebrow::before { content: ""; - width: 5px; height: 5px; - border-radius: 50%; - background: var(--muted-2); + width: 4px; height: 4px; + border-radius: 1px; + background: var(--accent); flex-shrink: 0; + transform: rotate(45deg); } .lp-h1 { @@ -4414,9 +4730,8 @@ select.control { cursor: pointer; } .lp-demo__card { background: var(--surface); border: 1px solid var(--border); - border-radius: var(--r-lg); + border-radius: var(--r-md); overflow: hidden; - box-shadow: var(--shadow-lg); } .lp-demo__head { display: flex; @@ -4559,7 +4874,7 @@ select.control { cursor: pointer; } gap: 0; background: var(--border); border: 1px solid var(--border); - border-radius: var(--r-lg); + border-radius: var(--r-md); overflow: hidden; } .lp-feat { @@ -4596,7 +4911,7 @@ select.control { cursor: pointer; } .lp-showcase { padding: clamp(48px, 5vw, 72px) clamp(24px, 5vw, 80px); border-top: 1px solid var(--divider); - background: color-mix(in srgb, var(--accent) 2.5%, var(--bg)); + background: var(--bg); } .lp-showcase__inner { max-width: var(--w-public); @@ -4675,8 +4990,8 @@ select.control { cursor: pointer; } font-weight: 600; } .lp-sess-pill--open { - background: rgba(111,192,147,.15); - border: 1px solid rgba(111,192,147,.3); + background: rgba(103,185,135,.15); + border: 1px solid rgba(103,185,135,.3); color: var(--pos); } .lp-sess-pill--closed { @@ -4824,7 +5139,7 @@ select.control { cursor: pointer; } gap: 1px; background: var(--border); border: 1px solid var(--border); - border-radius: var(--r-lg); + border-radius: var(--r-md); overflow: hidden; } .lp-seo__item { @@ -5083,127 +5398,192 @@ select.control { cursor: pointer; } padding-top: 2px; } -.db-live-alert { +/* live session banner */ +.db-live-banner { + background: var(--surface); + border: 1px solid rgba(103,185,135,.3); + border-radius: var(--r-md); + padding: 16px 20px; + margin-bottom: 16px; +} +.db-live-banner__top { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + margin-bottom: 14px; +} +.db-live-banner__status { display: flex; align-items: center; gap: 10px; - background: rgba(111,192,147,.07); - border: 1px solid rgba(111,192,147,.22); - border-radius: var(--r-md); - padding: 11px 16px; - margin-bottom: 24px; - font-size: .875rem; - color: var(--pos); + flex-wrap: wrap; } -.db-live-alert__pulse { - width: 8px; - height: 8px; +.db-live-dot { + width: 8px; height: 8px; border-radius: 50%; background: var(--pos); flex-shrink: 0; - box-shadow: 0 0 0 0 rgba(111,192,147,.4); - animation: pulse-ring 2s ease-in-out infinite; + animation: livepulse 2.2s ease-in-out infinite; } -@keyframes pulse-ring { - 0% { box-shadow: 0 0 0 0 rgba(111,192,147,.5); } - 70% { box-shadow: 0 0 0 6px rgba(111,192,147,0); } - 100% { box-shadow: 0 0 0 0 rgba(111,192,147,0); } +.db-live-label { + font-size: .68rem; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + color: var(--pos); +} +.db-live-name { + font-size: 1rem; + font-weight: 700; + color: var(--text-strong); +} +.db-live-since { + font-size: .8rem; + color: var(--text-muted); +} +.db-live-banner__stats { + display: flex; + align-items: center; + gap: 0; + flex-wrap: wrap; +} +.db-live-stat { + display: flex; + flex-direction: column; + gap: 3px; + padding-right: 24px; + margin-right: 24px; + border-right: 1px solid var(--border); +} +.db-live-stat:last-child { border-right: none; padding-right: 0; margin-right: 0; } +.db-live-stat--players { flex: 1; min-width: 0; } +.db-live-stat__label { + font-size: .6rem; + font-weight: 700; + letter-spacing: .07em; + text-transform: uppercase; + color: var(--text-muted); +} +.db-live-stat__val { + font-size: 1.2rem; + font-weight: 700; + color: var(--text-strong); + font-family: var(--font-mono); +} +.db-live-stat__val--accent { color: var(--accent); } +.db-live-stat__names { + font-size: .82rem; + color: var(--text-2); + font-weight: 500; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } -.db-live-alert__text { flex: 1; font-weight: 500; } -.db-live-alert__link { color: var(--pos); font-weight: 600; white-space: nowrap; } -.db-live-alert__link:hover { text-decoration: underline; } -.db-stat-grid { +/* overview stats strip */ +.db-overview-strip { display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 12px; - margin-bottom: 24px; -} -.db-stat { - background: var(--surface); + grid-template-columns: repeat(5, 1fr); + gap: 1px; + background: var(--border); border: 1px solid var(--border); border-radius: var(--r-md); - padding: 16px 18px; - display: flex; - align-items: center; - gap: 14px; -} -.db-stat__icon { - width: 40px; - height: 40px; - border-radius: var(--r-sm); - background: rgba(255,255,255,.05); - color: var(--text-muted); - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; -} -.db-stat__icon--accent { background: var(--accent-chip); border: 1px solid var(--accent-chip-bd); color: var(--accent); } -.db-stat__icon--pos { background: rgba(111,192,147,.12); color: var(--pos); } -.db-stat__icon--warn { background: rgba(224,177,92,.12); color: var(--warn); } -.db-stat__num { - display: block; - font-size: 1.65rem; - font-weight: 800; - color: var(--text-strong); - letter-spacing: -.035em; - line-height: 1.1; -} -.db-stat__label { - display: block; - font-size: .72rem; - color: var(--text-muted); - margin-top: 3px; - font-weight: 500; - letter-spacing: .02em; -} - -.db-cash { - display: flex; - align-items: stretch; - background: var(--surface); - border: 1px solid var(--border); - border-radius: var(--r-lg); overflow: hidden; margin-bottom: 16px; } -.db-cash__stat { - flex: 1; - padding: 16px 20px; +.db-overview-stat { + background: var(--surface); + padding: 20px 22px 18px; display: flex; flex-direction: column; - gap: 5px; + gap: 2px; +} +.db-overview-stat__label { + font-size: .6rem; + font-weight: 600; + letter-spacing: .07em; + text-transform: uppercase; + color: var(--text-muted); + margin-bottom: 4px; +} +.db-overview-stat__val { + font-size: 1.75rem; + font-weight: 800; + font-family: var(--font-mono); + letter-spacing: -.03em; + line-height: 1; + font-variant-numeric: tabular-nums; + color: var(--text-strong); +} +.db-overview-stat--players .db-overview-stat__val { color: var(--accent); } +.db-overview-stat--sessions .db-overview-stat__val { color: var(--text-strong); } +.db-overview-stat--cashin .db-overview-stat__val { color: var(--text-strong); } +.db-overview-stat--paidout .db-overview-stat__val { color: var(--pos); } +.db-overview-stat__sub { + font-size: .68rem; + color: var(--text-muted); + margin-top: 5px; +} + +/* league averages card */ +.db-averages { + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--r-md); + overflow: hidden; + margin-bottom: 16px; +} +.db-averages__title { + font-size: .65rem; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + color: var(--text-muted); + padding: 12px 20px; + margin: 0; + border-bottom: 1px solid var(--border); +} +.db-averages__grid { display: flex; flex-direction: column; } +.db-avg-row { + display: flex; + align-items: stretch; + border-bottom: 1px solid var(--border); +} +.db-avg-row:last-child { border-bottom: none; } +.db-avg-item { + flex: 1; + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + padding: 13px 20px; + border-right: 1px solid var(--border); min-width: 0; } -.db-cash__div { - width: 1px; - background: var(--border); - flex-shrink: 0; +.db-avg-item:last-child { border-right: none; } +.db-avg-label { + font-size: .78rem; + color: var(--text-2); } -.db-cash__label { - font-size: .68rem; - font-weight: 600; - color: var(--text-muted); - letter-spacing: .05em; - text-transform: uppercase; - font-family: var(--font-mono); - white-space: nowrap; -} -.db-cash__val { - font-size: 1.375rem; - font-weight: 800; +.db-avg-val { + font-size: .9375rem; + font-weight: 700; color: var(--text-strong); - letter-spacing: -.03em; - line-height: 1.1; + font-family: var(--font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; } +.db-cal__meta { + font-size: .75rem; + color: var(--text-muted); + margin-top: 2px; +} .db-cal { background: var(--surface); border: 1px solid var(--border); - border-radius: var(--r-lg); + border-radius: var(--r-md); padding: 16px 20px 18px; margin-bottom: 16px; position: relative; @@ -5254,13 +5634,20 @@ select.control { cursor: pointer; } opacity: .25; cursor: not-allowed; } +.db-cal__scroll { + overflow-x: auto; + -webkit-overflow-scrolling: touch; + margin: 0 -4px; + padding: 0 4px 4px; +} .db-cal__grid { display: grid; grid-template-rows: 14px repeat(7, 1fr); grid-auto-flow: column; - grid-auto-columns: 1fr; + grid-auto-columns: minmax(10px, 1fr); gap: 3px; height: 132px; + min-width: 560px; width: 100%; } .db-cal__mc { @@ -5313,358 +5700,617 @@ select.control { cursor: pointer; } box-shadow: 0 4px 16px rgba(0,0,0,.45); } -.db-nav-grid { +/* recent sessions + leaderboard two-col */ +.db-two-col { display: grid; - grid-template-columns: repeat(2, 1fr); - gap: 12px; + grid-template-columns: 1fr 1fr; + gap: 20px; + margin-bottom: 16px; } -.db-nav-tile { - background: var(--surface); - border: 1px solid var(--border); - border-radius: var(--r-lg); - padding: 20px; - display: flex; - align-items: flex-start; - gap: 16px; - text-decoration: none; - transition: border-color .15s, background .15s, box-shadow .15s; - position: relative; -} -.db-nav-tile:hover { - border-color: var(--accent-chip-bd); - background: rgba(155,140,240,.04); - box-shadow: 0 4px 24px rgba(0,0,0,.18); -} -.db-nav-tile__icon { - width: 44px; - height: 44px; - border-radius: 12px; - background: var(--accent-chip); - border: 1px solid var(--accent-chip-bd); - color: var(--accent); +.db-panel { display: flex; flex-direction: column; } +.db-panel__head { display: flex; align-items: center; - justify-content: center; - flex-shrink: 0; - transition: background .15s; + justify-content: space-between; + padding: 0 0 10px; } -.db-nav-tile__body { flex: 1; min-width: 0; } -.db-nav-tile__title-row { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; } -.db-nav-tile__title { - font-size: .9375rem; +.db-panel__title { + font-size: .875rem; font-weight: 700; color: var(--text-strong); + display: flex; + align-items: center; + gap: 8px; } -.db-nav-tile__count { +.db-panel__sub { font-size: .7rem; + font-weight: 500; color: var(--text-muted); +} +.db-panel__link { + font-size: .72rem; font-weight: 600; - background: var(--surface-sunk); + color: var(--text-muted); + text-decoration: none; +} +.db-panel__link:hover { color: var(--accent); } +.db-panel__empty { font-size: .8rem; color: var(--text-muted); padding: 12px 0; margin: 0; } + +/* shared soft-outline table container */ +.db-table { border: 1px solid var(--border); - border-radius: 999px; - padding: 2px 9px; - line-height: 1.6; + border-radius: var(--r-md); + overflow: hidden; +} + +/* recent session rows */ +.db-session-row { + display: flex; + align-items: center; + gap: 14px; + padding: 12px 16px; + text-decoration: none; + background: var(--surface); + border-bottom: 1px solid var(--border); + transition: background .12s; + position: relative; +} +.db-session-row:last-child { border-bottom: none; } +.db-session-row:hover { background: var(--surface-raised); } +.db-session-row--live { + background: rgba(103,185,135,.04); +} +.db-session-row--live::before { + content: ''; + position: absolute; + left: 0; top: 0; bottom: 0; + width: 3px; + background: var(--pos); +} +.db-session-row__num { + font-size: .82rem; + font-weight: 600; + color: var(--text-strong); white-space: nowrap; } -.db-nav-tile__desc { - font-size: .8125rem; +.db-session-row__meta { + flex: 1; + font-size: .72rem; color: var(--text-muted); - margin: 0; - line-height: 1.5; } -.db-nav-tile__arrow { - font-size: 17px; - color: var(--text-muted); - opacity: .3; - transition: opacity .15s, transform .15s; - flex-shrink: 0; - align-self: center; -} -.db-nav-tile:hover .db-nav-tile__arrow { opacity: .65; transform: translateX(4px); } - -/* Per-section tile accents */ -.db-nav-tile--sessions { - border-left: 3px solid rgba(111,192,147,.32); -} -.db-nav-tile--sessions .db-nav-tile__icon { - background: rgba(111,192,147,.12); - border: 1px solid rgba(111,192,147,.28); +.db-live-tag { color: var(--pos); + font-weight: 600; } -.db-nav-tile--sessions:hover { border-left-color: rgba(111,192,147,.55); } +.db-session-row__pot { + font-family: var(--font-mono); + font-size: .9rem; + font-weight: 700; + color: var(--text-strong); + white-space: nowrap; +} +.db-session-row__pot--live { color: var(--pos); } -.db-nav-tile--leaderboard { - border-left: 3px solid rgba(90,168,232,.28); +/* leaderboard snippet */ +.db-leader-row { + display: flex; + align-items: center; + gap: 12px; + padding: 12px 16px; + background: var(--surface); + border-bottom: 1px solid var(--border); } -.db-nav-tile--leaderboard .db-nav-tile__icon { - background: rgba(90,168,232,.09); - border: 1px solid rgba(90,168,232,.24); - color: #5aa8e8; +.db-leader-row:last-child { border-bottom: none; } +.db-leader-row--1 { background: rgba(244,196,48,.05); } +.db-leader-row--2 { background: rgba(176,184,193,.04); } +.db-leader-row--3 { background: rgba(200,121,65,.04); } +.db-leader-rank { + font-size: .78rem; + font-weight: 800; + font-family: var(--font-mono); + min-width: 20px; + color: var(--text-muted); +} +.db-leader-row--1 .db-leader-rank { color: #f4c430; } +.db-leader-row--2 .db-leader-rank { color: #b0b8c1; } +.db-leader-row--3 .db-leader-rank { color: #c87941; } +.db-leader-name { + flex: 1; + font-size: .875rem; + font-weight: 600; + color: var(--text-strong); +} +.db-leader-sess { + font-size: .7rem; + color: var(--text-muted); + font-family: var(--font-mono); + white-space: nowrap; +} +.db-leader-net { + font-family: var(--font-mono); + font-size: .9375rem; + font-weight: 700; + white-space: nowrap; } -.db-nav-tile--leaderboard:hover { border-left-color: rgba(90,168,232,.5); } -.db-nav-tile--players { - border-left: 3px solid rgba(155,140,240,.3); +/* quick nav — flat, no card background */ +.db-quicknav { + display: grid; + grid-template-columns: repeat(5, 1fr); + gap: 0; + border-top: 1px solid var(--border); + margin-top: 8px; } -.db-nav-tile--players .db-nav-tile__icon { - background: var(--accent-chip); - border: 1px solid var(--accent-chip-bd); - color: var(--accent); +.db-quicknav__item { + display: flex; + flex-direction: column; + gap: 4px; + padding: 16px 18px; + text-decoration: none; + border-right: 1px solid var(--border); + transition: background .12s; } -.db-nav-tile--players:hover { border-left-color: rgba(155,140,240,.55); } - -.db-nav-tile--ledger { - border-left: 3px solid rgba(224,177,92,.28); +.db-quicknav__item:last-child { border-right: none; } +.db-quicknav__item:hover { background: var(--surface); } +.db-quicknav__title { + font-size: .8rem; + font-weight: 700; + color: var(--text-strong); + display: flex; + align-items: center; + gap: 6px; } -.db-nav-tile--ledger .db-nav-tile__icon { - background: rgba(224,177,92,.1); - border: 1px solid rgba(224,177,92,.24); - color: var(--warn); -} -.db-nav-tile--ledger:hover { border-left-color: rgba(224,177,92,.5); } - -.db-nav-tile--seasons { - border-left: 3px solid rgba(155,140,240,.28); -} -.db-nav-tile--seasons .db-nav-tile__icon { - background: rgba(155,140,240,.1); - border: 1px solid rgba(155,140,240,.24); - color: var(--accent); -} -.db-nav-tile--seasons:hover { border-left-color: rgba(155,140,240,.55); } - -/* Live tile overrides the sessions color */ -.db-nav-tile--sessions.db-nav-tile--live { - border-left-color: rgba(111,192,147,.55); - background: rgba(111,192,147,.04); -} -.db-nav-tile--sessions.db-nav-tile--live:hover { - border-left-color: rgba(111,192,147,.78); - background: rgba(111,192,147,.08); -} -.db-nav-tile--sessions.db-nav-tile--live .db-nav-tile__icon { - background: rgba(111,192,147,.18); - border-color: rgba(111,192,147,.4); +.db-quicknav__desc { + font-size: .72rem; + color: var(--text-muted); + line-height: 1.4; } @media (max-width: 960px) { - .db-stat-grid { grid-template-columns: repeat(2, 1fr); } - .db-nav-grid { grid-template-columns: 1fr; } + .db-overview-strip { grid-template-columns: repeat(3, 1fr); } + .db-overview-strip .db-overview-stat:last-child { grid-column: span 3; border-top: 1px solid var(--border); } + .db-quicknav { grid-template-columns: repeat(3, 1fr); } + /* averages: 2-up grid instead of 5-wide flex row */ + .db-avg-row { + display: grid; + grid-template-columns: 1fr 1fr; + } + .db-avg-item { + flex-direction: column; + align-items: flex-start; + justify-content: flex-start; + gap: 4px; + border-right: none; + border-bottom: 1px solid var(--border); + } + .db-avg-item:nth-child(odd) { border-right: 1px solid var(--border); } + .db-avg-item:last-child { border-bottom: none; } + .db-avg-row:last-child .db-avg-item { border-bottom: none; } } @media (max-width: 700px) { - .db-cash { flex-wrap: wrap; } - .db-cash__stat { flex: 1 1 40%; } - .db-cash__div { display: none; } - .db-cal__grid { height: 110px; } + .db-two-col { grid-template-columns: 1fr; } + .db-overview-strip { grid-template-columns: repeat(2, 1fr); } + .db-overview-strip .db-overview-stat:last-child { grid-column: span 2; } + .db-cal__grid { height: 100px; } + .db-quicknav { grid-template-columns: repeat(2, 1fr); } + .db-live-banner__stats { flex-wrap: wrap; gap: 12px; } + .db-live-stat { border-right: none; padding-right: 0; margin-right: 0; } } @media (max-width: 560px) { .db-header { flex-direction: column; gap: 12px; } - .db-cash__val { font-size: 1.125rem; } - .db-cal__grid { height: 96px; } - .db-cal__mc { font-size: .52rem; } + .db-cal__grid { height: 88px; } + .db-cal__mc { font-size: .5rem; } + .db-quicknav { grid-template-columns: 1fr 1fr; } } /* ================================================================ LEAGUES INDEX — card list ================================================================ */ -.li-board { +/* ---- page header strip ---- */ +.li-page-header { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 24px; + padding-bottom: 24px; + border-bottom: 1px solid var(--border); + margin-bottom: 24px; +} +.li-page-header__title { + font-size: clamp(1.75rem, 3vw, 2.5rem); + font-weight: 800; + color: var(--text-strong); + line-height: 1.1; + letter-spacing: -.02em; + margin: 0; +} +.li-page-header__stats { + display: flex; + gap: 0; + flex-shrink: 0; + border: 1px solid var(--border); + border-radius: var(--r-md); + overflow: hidden; +} +.li-header-stat { display: flex; flex-direction: column; - gap: 10px; + gap: 4px; + padding: 12px 22px; + border-right: 1px solid var(--border); } +.li-header-stat:last-child { border-right: none; } +.li-header-stat__label { + font-size: .6rem; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + color: var(--text-muted); + white-space: nowrap; +} +.li-header-stat__val { + font-size: 1.375rem; + font-weight: 800; + color: var(--text-strong); + font-family: var(--font-mono); + line-height: 1; +} + +/* ---- split layout ---- */ +.leagues-split { + display: grid; + grid-template-columns: 370px 1fr; + gap: 24px; + align-items: start; +} +.leagues-split__form { position: sticky; top: 24px; } + +/* ---- new league form ---- */ +.li-new-form { + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--r-md); + padding: 22px; + display: flex; + flex-direction: column; + gap: 18px; +} +.li-new-form__title { + font-size: 1.25rem; + font-weight: 700; + color: var(--text-strong); + margin: 0 0 4px; +} +.li-new-form__field { display: flex; flex-direction: column; gap: 7px; } +.li-new-form__label { + font-size: .68rem; + font-weight: 700; + letter-spacing: .07em; + text-transform: uppercase; + color: var(--text-muted); +} +.li-new-form__input { + background: var(--bg); + border: 1px solid var(--border); + border-radius: var(--r-sm); + color: var(--text); + font: 400 14px/1 var(--font-ui); + padding: 9px 12px; + width: 100%; + box-sizing: border-box; + outline: none; + transition: border-color .15s; +} +.li-new-form__input:focus { border-color: var(--accent); } +.li-new-form__textarea { resize: vertical; min-height: 110px; line-height: 1.5; } +.li-new-form__hint { font-size: .72rem; color: var(--text-muted); margin: 0; line-height: 1.4; } +.li-new-form__two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } +.li-input-prefix-wrap { position: relative; display: flex; align-items: center; } +.li-input-prefix { + position: absolute; + left: 10px; + font: 400 14px/1 var(--font-mono); + color: var(--text-muted); + pointer-events: none; +} +.li-input-has-prefix { padding-left: 22px; } +.li-new-form__submit { + width: 100%; + padding: 12px; + background: var(--accent); + color: #fff; + border: none; + border-radius: var(--r-sm); + font: 700 13px/1 var(--font-ui); + letter-spacing: .06em; + text-transform: uppercase; + cursor: pointer; + transition: opacity .15s; +} +.li-new-form__submit:hover { opacity: .88; } + +/* ---- visibility toggle ---- */ +.li-visibility-toggle { + display: flex; + gap: 0; + border: 1px solid var(--border); + border-radius: var(--r-sm); + overflow: hidden; +} +.li-vis-btn { + flex: 1; + padding: 8px 0; + background: transparent; + border: none; + color: var(--text-muted); + font: 600 12px/1 var(--font-ui); + cursor: pointer; + transition: background .12s, color .12s; +} +.li-vis-btn + .li-vis-btn { border-left: 1px solid var(--border); } +.li-vis-btn.is-on { background: var(--accent); color: #fff; } + +/* ---- preset chips ---- */ +.li-preset-row { + display: flex; + gap: 6px; + align-items: center; + flex-wrap: wrap; +} +.li-preset-btn { + padding: 6px 11px; + background: var(--surface-2); + border: 1px solid var(--border); + border-radius: var(--r-sm); + color: var(--text-2); + font: 600 12px/1 var(--font-mono); + cursor: pointer; + transition: background .12s, border-color .12s, color .12s; + flex-shrink: 0; +} +.li-preset-btn:hover { border-color: var(--accent); color: var(--accent); } +.li-preset-btn.is-on { background: color-mix(in srgb, var(--accent) 15%, transparent); border-color: var(--accent); color: var(--accent); } +.li-preset-custom { + flex: 1; + min-width: 60px; + padding: 6px 9px; + background: var(--bg); + border: 1px solid var(--border); + border-radius: var(--r-sm); + color: var(--text); + font: 400 13px/1 var(--font-mono); + outline: none; +} +.li-preset-custom:focus { border-color: var(--accent); } + +/* ---- list toolbar ---- */ +.li-toolbar { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 14px; + flex-wrap: wrap; +} +.li-search { + flex: 1; + min-width: 160px; + padding: 8px 14px; + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--r-sm); + color: var(--text); + font: 400 13px/1 var(--font-ui); + outline: none; + transition: border-color .15s; +} +.li-search:focus { border-color: var(--accent); } +.li-filter-pills { display: flex; gap: 4px; } +.li-filter-btn { + padding: 7px 13px; + background: transparent; + border: 1px solid var(--border); + border-radius: var(--r-sm); + color: var(--text-muted); + font: 600 11px/1 var(--font-ui); + letter-spacing: .04em; + text-transform: uppercase; + cursor: pointer; + transition: all .12s; +} +.li-filter-btn:hover { color: var(--text); border-color: var(--border-strong); } +.li-filter-btn.is-on { background: var(--accent); border-color: var(--accent); color: #fff; box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 28%, transparent); } +.li-sort-tabs { display: flex; align-items: center; gap: 4px; margin-left: auto; } +.li-sort-label { + font-size: .65rem; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + color: var(--text-muted); + padding-right: 6px; +} +.li-sort-btn { + padding: 6px 10px; + background: transparent; + border: none; + border-bottom: 2px solid transparent; + color: var(--text-muted); + font: 600 11px/1 var(--font-ui); + letter-spacing: .04em; + text-transform: uppercase; + cursor: pointer; + transition: color .12s, border-color .12s; +} +.li-sort-btn:hover { color: var(--text); } +.li-sort-btn.is-on { color: var(--text-strong); border-bottom-color: var(--accent); } + +/* ---- league cards ---- */ +.li-board { display: flex; flex-direction: column; gap: 10px; } .li-card { background: var(--surface); border: 1px solid var(--border); - border-radius: var(--r-lg); + border-radius: var(--r-md); overflow: hidden; - transition: border-color .15s, box-shadow .15s; - display: flex; - flex-direction: row; + transition: border-color .15s; } -.li-card:hover { border-color: var(--border-strong); box-shadow: 0 2px 16px rgba(0,0,0,.14); } -.li-card--live { border-color: rgba(111,192,147,.3); } -.li-card--live:hover { border-color: rgba(111,192,147,.5); } +.li-card:hover { border-color: var(--border-strong); } +.li-card--live { border-color: rgba(103,185,135,.35); } +.li-card--live:hover { border-color: rgba(103,185,135,.6); } -/* left initial badge column */ -.li-card__aside { - width: 56px; - flex-shrink: 0; +.li-card__top { display: flex; align-items: center; - justify-content: center; - background: var(--surface-sunk); - border-right: 1px solid var(--border); -} -.li-card--live .li-card__aside { - background: rgba(111,192,147,.05); - border-right-color: rgba(111,192,147,.2); -} -.li-card__initial { - font-size: 1.375rem; - font-weight: 800; - color: var(--accent); - letter-spacing: -.03em; - line-height: 1; - opacity: .75; - user-select: none; -} -.li-card--live .li-card__initial { color: var(--pos); } - -/* right content column */ -.li-card__body { - flex: 1; - min-width: 0; - display: flex; - flex-direction: column; -} - -/* top section: name + badges + desc on left, stats on right */ -.li-card__head { - display: flex; - align-items: flex-start; justify-content: space-between; - gap: 20px; - padding: 18px 20px 14px; + gap: 16px; + padding: 16px 20px; + position: relative; + cursor: pointer; } -.li-card__info { flex: 1; min-width: 0; } .li-card__name-row { display: flex; align-items: center; gap: 8px; - margin-bottom: 6px; - flex-wrap: wrap; + min-width: 0; + flex: 1; } .li-card__name { - font-size: 1.05rem; + font-size: 1.1rem; font-weight: 700; color: var(--text-strong); text-decoration: none; - line-height: 1.25; + white-space: nowrap; +} +.li-card__name::before { + content: ''; + position: absolute; + inset: 0; } .li-card__name:hover { color: var(--accent); } -.li-card__chips { - display: flex; - gap: 5px; - flex-wrap: wrap; - margin-bottom: 6px; -} -.li-card__desc { - font-size: .8125rem; +.li-open-btn, .li-badge, .li-pill { position: relative; z-index: 1; } +.li-card__season { + font-size: .72rem; color: var(--text-muted); - margin: 0; - line-height: 1.5; + white-space: nowrap; } -.li-card__stats { - display: flex; - gap: 20px; +.li-pill { + padding: 2px 8px; + border-radius: 100px; + font: 700 10px/1.5 var(--font-ui); + letter-spacing: .04em; + text-transform: uppercase; flex-shrink: 0; - align-self: flex-start; - padding-top: 2px; } -.li-stat { +.li-pill--live { background: rgba(103,185,135,.15); color: var(--pos); border: 1px solid rgba(103,185,135,.3); } +.li-pill--idle { background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--border); } +.li-badge { + padding: 2px 8px; + border-radius: var(--r-sm); + border: 1px solid var(--border); + font: 600 10px/1.5 var(--font-ui); + letter-spacing: .04em; + text-transform: uppercase; + color: var(--text-muted); + flex-shrink: 0; +} +.li-open-btn { + padding: 6px 16px; + background: var(--accent); + color: #fff; + border-radius: var(--r-sm); + font: 700 12px/1 var(--font-ui); + text-decoration: none; + letter-spacing: .04em; + text-transform: uppercase; + white-space: nowrap; + transition: opacity .15s; + flex-shrink: 0; +} +.li-open-btn:hover { opacity: .85; } + +/* stats + leaders row */ +.li-card__body { + display: flex; + align-items: stretch; + border-top: 1px solid var(--border); + background: var(--surface-sunk); +} +.li-card__stats-col { display: flex; flex-direction: column; - align-items: flex-end; - gap: 2px; -} -.li-stat span { - font-size: .65rem; - color: var(--text-muted); - font-weight: 500; - letter-spacing: .05em; - text-transform: uppercase; - white-space: nowrap; -} -.li-stat strong { - font-size: 1rem; - font-weight: 700; - color: var(--text-strong); - font-variant-numeric: tabular-nums; - font-family: var(--font-mono); -} - -/* leaders strip — podium chips */ -.li-card__leaders { - display: flex; - align-items: center; - gap: 0; - padding: 9px 20px; - border-top: 1px solid var(--border); - background: rgba(255,255,255,.015); - overflow: hidden; -} -.li-card__leaders-label { - font-size: .6rem; - font-weight: 600; - letter-spacing: .09em; - text-transform: uppercase; - color: var(--text-muted); - margin-right: 14px; - white-space: nowrap; + gap: 5px; + padding: 12px 20px; + border-right: 1px solid var(--border); flex-shrink: 0; } -.li-podium { +.li-card__leaders-col { display: flex; - gap: 7px; + flex-direction: column; + gap: 6px; + padding: 12px 20px; flex: 1; min-width: 0; - flex-wrap: wrap; } -.li-podium-item { +.li-stat-label { + font-size: .6rem; + font-weight: 700; + letter-spacing: .07em; + text-transform: uppercase; + color: var(--text-muted); + white-space: nowrap; +} +.li-stat-num { + font-size: 1rem; + font-weight: 700; + font-family: var(--font-mono); + color: var(--text-strong); + font-variant-numeric: tabular-nums; +} +.li-leaders-list { display: flex; flex-direction: column; gap: 3px; } +.li-leader-row { display: flex; align-items: center; - gap: 5px; - padding: 4px 10px 4px 7px; - border-radius: var(--r-md); - border: 1px solid var(--border); - background: var(--surface-sunk); - flex-shrink: 0; + gap: 8px; + font-size: .78rem; } -.li-podium-item--1 { border-color: rgba(244,196,48,.3); background: rgba(244,196,48,.05); } -.li-podium-item--2 { border-color: rgba(176,184,193,.2); background: rgba(176,184,193,.04); } -.li-podium-item--3 { border-color: rgba(200,121,65,.22); background: rgba(200,121,65,.04); } -.li-podium-rank { +.li-leader-rank { font-family: var(--font-mono); - font-size: .65rem; + font-size: .62rem; font-weight: 700; color: var(--text-muted); + min-width: 18px; } -.li-podium-item--1 .li-podium-rank { color: #f4c430; } -.li-podium-item--2 .li-podium-rank { color: #b0b8c1; } -.li-podium-item--3 .li-podium-rank { color: #c87941; } -.li-podium-name { - font-size: .8125rem; - color: var(--text-2); -} -.li-podium-net { - font-family: var(--font-mono); - font-size: .75rem; - font-variant-numeric: tabular-nums; - font-weight: 600; -} +.li-leader-name { color: var(--text-2); flex: 1; } +.li-leader-net { font-family: var(--font-mono); font-size: .78rem; font-weight: 600; } -/* footer: meta + actions */ +/* footer */ .li-card__footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; - padding: 9px 20px; + padding: 8px 20px; border-top: 1px solid var(--border); } -.li-card__meta { - font-size: .75rem; +.li-card__footer-meta { + font-size: .7rem; color: var(--text-muted); - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + text-transform: uppercase; + letter-spacing: .05em; + font-weight: 600; } -.li-card__actions { - display: flex; - align-items: center; - gap: 4px; - flex-shrink: 0; +.li-card__footer-links { display: flex; align-items: center; gap: 2px; } +.li-footer-link { + font-size: .7rem; + font-weight: 600; + letter-spacing: .05em; + text-transform: uppercase; + color: var(--text-muted); + text-decoration: none; + padding: 4px 9px; + border-radius: var(--r-sm); + transition: color .12s, background .12s; } +.li-footer-link:hover { color: var(--text); background: var(--surface-raised); } +.li-empty-search { color: var(--text-muted); font-size: 14px; padding: 24px 0; } .li-action-link { font-size: .75rem; color: var(--text-muted); @@ -5676,17 +6322,12 @@ select.control { cursor: pointer; } } .li-action-link:hover { color: var(--text-2); background: var(--surface-raised); } -@media (max-width: 640px) { - .li-card__aside { width: 44px; } - .li-card__initial { font-size: 1.1rem; } - .li-card__head { flex-direction: column; gap: 12px; } - .li-card__stats { flex-direction: row; align-self: auto; } - .li-stat { align-items: flex-start; } - .li-card__footer { flex-wrap: wrap; gap: 8px; } - .li-action-link { display: none; } -} -@media (max-width: 400px) { - .li-card__aside { display: none; } +@media (max-width: 860px) { + .leagues-split { grid-template-columns: 1fr; } + .leagues-split__form { position: static; } + .li-page-header { flex-direction: column; align-items: flex-start; } + .li-card__body { flex-wrap: wrap; } + .li-footer-link { display: none; } } @@ -5780,8 +6421,7 @@ select.control { cursor: pointer; } padding: 8px; background: var(--surface); border: 1px solid var(--border-strong); - border-radius: var(--r-lg); - box-shadow: var(--shadow-sm); + border-radius: var(--r-md); } .explore-search-row .field-input { flex: 1; @@ -5834,17 +6474,16 @@ select.control { cursor: pointer; } .ex-card { background: var(--surface); border: 1px solid var(--border); - border-radius: var(--r-lg); + border-radius: var(--r-md); padding: 20px; text-decoration: none; display: flex; flex-direction: column; gap: 0; - transition: border-color .15s, box-shadow .15s; + transition: border-color .15s; } .ex-card:hover { - border-color: var(--accent-chip-bd); - box-shadow: 0 4px 24px rgba(0,0,0,.2); + border-color: var(--border-strong); } .ex-card__initial { width: 40px; @@ -6003,9 +6642,7 @@ select.control { cursor: pointer; } .lp-callout { padding: clamp(56px, 6vw, 88px) clamp(24px, 5vw, 80px); border-top: 1px solid var(--divider); - background: - radial-gradient(ellipse 48% 62% at 10% 52%, rgba(155,140,240,.045) 0%, transparent 62%), - var(--bg); + background: var(--bg); } .lp-callout__inner { max-width: var(--w-public); @@ -6111,9 +6748,8 @@ select.control { cursor: pointer; } .auth-split__brand-mark { width: 28px; height: 28px; - border-radius: 7px; + border-radius: 5px; background: var(--accent); - box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); position: relative; flex: none; } @@ -6268,9 +6904,7 @@ select.control { cursor: pointer; } justify-content: center; position: relative; overflow: hidden; - background: - radial-gradient(ellipse 76% 76% at 50% 48%, rgba(155,140,240,.13) 0%, rgba(155,140,240,.045) 48%, transparent 72%), - color-mix(in srgb, var(--accent) 5%, var(--bg)); + background: color-mix(in srgb, var(--accent) 4%, var(--bg)); border-left: 1px solid var(--divider); } @@ -6400,10 +7034,10 @@ select.control { cursor: pointer; } transition: none; } .error-pg--403 .error-pg__suit { - color: rgba(155,140,240,.06); + color: rgba(129,119,183,.06); } .error-pg--500 .error-pg__suit { - color: rgba(224,177,92,.07); + color: rgba(197,164,90,.07); } .error-pg__body { @@ -6536,14 +7170,14 @@ select.control { cursor: pointer; } border: 1px solid var(--border); } .lp-feed__pill--cashout { - background: rgba(111,192,147,.12); + background: rgba(103,185,135,.12); color: var(--pos); - border: 1px solid rgba(111,192,147,.28); + border: 1px solid rgba(103,185,135,.28); } .lp-feed__pill--rebuy { - background: rgba(224,177,92,.1); + background: rgba(197,164,90,.1); color: var(--warn); - border: 1px solid rgba(224,177,92,.28); + border: 1px solid rgba(197,164,90,.28); } .lp-feed__amt { @@ -6567,6 +7201,542 @@ select.control { cursor: pointer; } padding: 11px 16px; } +/* ================================================================ + LANDING OVERHAUL + ================================================================ */ +.home-hero { + min-height: auto; + padding: clamp(52px, 7vw, 104px) var(--gutter) clamp(44px, 6vw, 76px); + border-bottom: 1px solid var(--divider); + background: transparent; +} +.home-hero__inner { + width: min(100%, var(--w-public)); + margin: 0 auto; + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(440px, 1.02fr); + gap: clamp(38px, 5vw, 84px); + align-items: center; +} +.home-hero__copy { + max-width: 640px; +} +.home-kicker { + display: inline-flex; + align-items: center; + gap: 9px; + margin: 0 0 22px; + color: var(--muted); + font: 700 10.5px/1 var(--font-mono); + letter-spacing: .22em; + text-transform: uppercase; +} +.home-kicker::before { + content: ""; + width: 22px; + height: 2px; + background: var(--accent); + flex: none; +} +.home-workflow .home-kicker::before { background: var(--accent2); } +.home-proof-panel .home-kicker::before { background: var(--accent3); } +.home-final .home-kicker::before { background: var(--pos); } +.home-title { + margin: 0; + max-width: 13ch; + color: var(--text-strong); + font: 900 clamp(44px, 6vw, 82px)/.94 var(--font-display); + letter-spacing: -.03em; +} +.home-sub { + max-width: 54ch; + margin: 24px 0 0; + color: var(--text-body); + font-size: clamp(15px, 1.15vw, 17px); + line-height: 1.7; +} +.home-actions { + display: flex; + flex-wrap: wrap; + gap: 10px; + margin-top: 28px; +} +.home-actions--center { + justify-content: center; +} +.home-proof { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 8px 18px; + margin-top: 30px; + padding-top: 24px; + border-top: 1px solid var(--divider); +} +.home-proof span { + display: inline-flex; + align-items: center; + gap: 8px; + color: var(--muted); + font: 600 12px/1 var(--font-ui); +} +.home-proof span::before { + content: ""; + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--hue, var(--accent)); + flex: none; +} +.home-proof span:nth-child(1) { --hue: var(--accent); } +.home-proof span:nth-child(2) { --hue: var(--accent2); } +.home-proof span:nth-child(3) { --hue: var(--accent3); } +.home-proof span:nth-child(4) { --hue: var(--warn); } +.home-board { + position: relative; + min-width: 0; + border: 1px solid var(--border-strong); + border-radius: var(--r-lg); + background: var(--surface); + box-shadow: var(--shadow-xl); + overflow: hidden; +} +.home-board__top, +.home-board__footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 14px; + padding: 16px 18px; + border-bottom: 1px solid var(--border); + background: var(--surface-head); +} +.home-board__top { + background: color-mix(in srgb, var(--accent) 9%, var(--surface-head)); +} +.home-board__footer { + border-bottom: 0; + background: color-mix(in srgb, var(--accent) 9%, var(--surface-head)); +} +.home-board__top strong { + display: block; + margin-top: 4px; + color: var(--text-strong); + font-size: 18px; +} +.home-board__eyebrow, +.home-board__footer span, +.home-board__metrics span, +.home-ledger__row--head span, +.home-table__row--head span { + color: var(--faint); + font: 800 10px/1 var(--font-mono); + letter-spacing: .11em; + text-transform: uppercase; +} +.home-board__status { + padding: 5px 10px; + border: 1px solid var(--pos-tint-bd); + border-radius: var(--r-sm); + background: var(--pos-tint); + color: var(--pos); + font: 800 11px/1 var(--font-ui); + text-transform: uppercase; +} +.home-board__metrics { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + border-bottom: 1px solid var(--border); +} +.home-board__metrics--four { + grid-template-columns: repeat(4, minmax(0, 1fr)); +} +.home-board__metrics div { + display: grid; + gap: 7px; + padding: 15px 18px; + border-right: 1px solid var(--border); +} +.home-board__metrics div:last-child { + border-right: 0; +} +.home-board__metrics strong, +.home-board__footer strong { + color: var(--text-strong); + font: 800 18px/1 var(--font-mono); + font-variant-numeric: tabular-nums; +} +.home-ledger__row { + display: grid; + grid-template-columns: 54px minmax(0, 1fr) 86px 88px; + gap: 12px; + align-items: center; + min-height: 44px; + padding: 0 18px; + border-bottom: 1px solid var(--divider); +} +.home-ledger__row:last-child { + border-bottom: 0; +} +.home-ledger__row span { + color: var(--faint); + font: 700 11px/1 var(--font-mono); +} +.home-ledger__row strong { + min-width: 0; + overflow: hidden; + color: var(--text-strong); + font-size: 14px; + text-overflow: ellipsis; + white-space: nowrap; +} +.home-ledger__row em { + justify-self: start; + padding: 4px 8px; + border: 1px solid var(--border); + border-radius: var(--r-sm); + background: var(--surface-sunk); + color: var(--muted); + font: normal 800 10px/1 var(--font-ui); + text-transform: uppercase; +} +.home-ledger__row b { + color: var(--num); + font: 800 13px/1 var(--font-mono); + text-align: right; +} +.home-board__footer { + border-top: 1px solid var(--border); + border-bottom: 0; +} +.home-strip { + border-bottom: 1px solid var(--divider); + background: var(--surface-sunk); +} +.home-strip__inner { + width: min(100%, var(--w-public)); + margin: 0 auto; + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); +} +.home-strip__inner div { + --hue: var(--accent); + min-height: 96px; + padding: 22px clamp(20px, 2.4vw, 30px); + border-right: 1px solid var(--border); + display: grid; + align-content: center; + gap: 9px; +} +.home-strip__inner div:nth-child(1) { --hue: var(--accent); } +.home-strip__inner div:nth-child(2) { --hue: var(--accent2); } +.home-strip__inner div:nth-child(3) { --hue: var(--accent3); } +.home-strip__inner div:nth-child(4) { --hue: var(--warn); } +.home-strip__inner div:last-child { + border-right: 0; +} +.home-strip__inner strong { + display: inline-flex; + align-items: center; + gap: 10px; + font-family: var(--font-display); + font-weight: 800; + color: var(--text-strong); + font-size: 17px; + letter-spacing: -.01em; + line-height: 1.1; +} +.home-strip__inner strong::before { + content: ""; + width: 9px; + height: 9px; + border-radius: 2px; + background: var(--hue); + flex: none; +} +.home-strip__inner span { + color: var(--muted); + font-size: 13px; + line-height: 1.4; +} +.home-section, +.home-workflow, +.home-proof-panel, +.home-final { + width: min(100%, var(--w-public)); + margin: 0 auto; + padding: clamp(44px, 5vw, 68px) var(--gutter); +} +.home-section__head { + display: grid; + gap: 12px; + max-width: 760px; + margin-bottom: 40px; +} +.home-section__head h2, +.home-workflow__copy h2, +.home-proof-panel__copy h2, +.home-final h2 { + margin: 0; + color: var(--text-strong); + font: 800 clamp(27px, 3.6vw, 46px)/1.04 var(--font-display); + letter-spacing: -.025em; +} +.home-feature-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 1px; + background: var(--border); + border-block: 1px solid var(--border); +} +.home-feature-grid article { + --hue: var(--accent); + min-height: 208px; + padding: 26px 24px; + background: var(--bg); + display: flex; + flex-direction: column; + position: relative; + transition: background 160ms ease; +} +.home-feature-grid article:hover { + background: color-mix(in srgb, var(--hue) 6%, var(--surface)); +} +.home-feature-grid article:nth-child(2) { --hue: var(--accent2); } +.home-feature-grid article:nth-child(3) { --hue: var(--accent3); } +.home-feature-grid article:nth-child(4) { --hue: var(--warn); } +.home-feature-grid article span { + color: var(--hue); + font: 900 44px/1 var(--font-display); + letter-spacing: -.03em; +} +.home-feature-grid h3 { + margin: 34px 0 12px; + color: var(--text-strong); + font-family: var(--font-display); + font-weight: 700; + font-size: 19px; + letter-spacing: -.01em; +} +.home-feature-grid p, +.home-workflow__copy p, +.home-proof-panel__copy p, +.home-final p { + margin: 0; + color: var(--muted); + font-size: 14px; + line-height: 1.65; +} +.home-workflow { + border-top: 1px solid var(--divider); + display: grid; + grid-template-columns: minmax(0, .82fr) minmax(420px, 1fr); + gap: clamp(30px, 5vw, 64px); + align-items: start; +} +.home-workflow__copy { + display: grid; + gap: 16px; +} +.home-steps { + display: grid; + border-top: 1px solid var(--border); +} +.home-steps div { + --hue: var(--accent); + display: grid; + grid-template-columns: 108px 1fr; + gap: 20px; + align-items: baseline; + padding: 18px 4px 18px 18px; + border-bottom: 1px solid var(--divider); + border-left: 2px solid var(--hue); +} +.home-steps div:nth-child(1) { --hue: var(--accent3); } +.home-steps div:nth-child(2) { --hue: var(--warn); } +.home-steps div:nth-child(3) { --hue: var(--pos); } +.home-steps div:nth-child(4) { --hue: var(--accent2); } +.home-steps div:last-child { + border-bottom: 0; +} +.home-steps span { + color: var(--hue); + font: 700 11px/1.3 var(--font-mono); + letter-spacing: .14em; + text-transform: uppercase; +} +.home-steps strong { + color: var(--text-body); + font-weight: 500; + font-size: 15px; + line-height: 1.55; +} +.home-proof-panel { + display: grid; + grid-template-columns: minmax(0, 1.15fr) minmax(340px, .85fr); + gap: clamp(30px, 5vw, 58px); + align-items: center; + border-top: 1px solid var(--divider); +} +.home-proof-panel__table { + border: 1px solid var(--border-strong); + border-radius: var(--r-lg); + background: var(--surface); + box-shadow: var(--shadow-lg); + overflow: hidden; +} +.home-table__row { + display: grid; + grid-template-columns: 60px minmax(0, 1fr) 84px 100px 92px; + gap: 12px; + align-items: center; + min-height: 48px; + padding: 0 18px; + border-bottom: 1px solid var(--divider); +} +.home-table__row:last-child { + border-bottom: 0; +} +.home-table__row--head { + background: var(--surface-head); + border-bottom-color: var(--border); +} +.home-table__row strong { + color: var(--text-strong); +} +.home-table__row span { + color: var(--muted); + font-size: 13px; +} +.home-table__row:not(.home-table__row--head) span:first-child { + font-family: var(--font-mono); + font-weight: 700; + color: var(--faint); +} +.home-table__row:nth-child(2) span:first-child { color: var(--accent); } +.home-table__row:nth-child(3) span:first-child { color: var(--accent2); } +.home-table__row:nth-child(4) span:first-child { color: var(--accent3); } +.home-table__row b { + font: 800 13px/1 var(--font-mono); + font-variant-numeric: tabular-nums; +} +.home-proof-panel__copy { + display: grid; + gap: 16px; +} +.home-link-row { + display: flex; + flex-wrap: wrap; + gap: 6px 24px; + margin-top: 12px; +} +.home-link-row a { + display: inline-flex; + align-items: center; + gap: 7px; + padding: 9px 4px; + color: var(--text-2); + font-size: 13.5px; + font-weight: 600; + border-bottom: 1px solid transparent; + transition: color 140ms, border-color 140ms; +} +.home-link-row a::after { + content: "→"; + color: var(--accent); + font-size: 13px; + transition: transform 160ms ease; +} +.home-link-row a:hover { + color: var(--text-strong); + border-bottom-color: var(--accent); +} +.home-link-row a:hover::after { transform: translateX(3px); } +.home-final { + text-align: center; + margin: clamp(20px, 3vw, 40px) auto clamp(40px, 5vw, 64px); + padding: clamp(44px, 6vw, 76px) var(--gutter); + border: 1px solid var(--border-strong); + border-radius: var(--r-lg); + background: var(--surface); +} +.home-final h2 { + max-width: 780px; + margin: 0 auto; +} +.home-final .home-kicker { + margin-bottom: 18px; +} +.home-final .home-actions--center { + margin-top: 32px; +} +@media (max-width: 980px) { + .home-hero__inner, + .home-workflow, + .home-proof-panel { + grid-template-columns: 1fr; + } + .home-board { + max-width: 720px; + } + .home-strip__inner, + .home-feature-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} +@media (max-width: 680px) { + .home-hero, + .home-section, + .home-workflow, + .home-proof-panel, + .home-final { + padding-left: 16px; + padding-right: 16px; + } + .home-title { + max-width: 12ch; + font-size: 38px; + } + .home-board__metrics, + .home-strip__inner, + .home-feature-grid { + grid-template-columns: 1fr; + } + .home-board__metrics div, + .home-strip__inner div { + border-right: 0; + border-bottom: 1px solid var(--border); + } + .home-board__metrics div:last-child, + .home-strip__inner div:last-child { + border-bottom: 0; + } + .home-feature-grid article { + min-height: 0; + } + .home-ledger__row { + grid-template-columns: 42px minmax(0, 1fr) 70px; + } + .home-ledger__row span:first-child, + .home-ledger__row--head span:first-child { + display: none; + } + .home-ledger__row b { + display: none; + } + .home-table__row { + grid-template-columns: 44px minmax(0, 1fr) 92px; + } + .home-table__row span:nth-child(3), + .home-table__row span:nth-child(5) { + display: none; + } + .home-actions .btn { + width: 100%; + justify-content: center; + } +} + /* ================================================================ LEGAL DOCUMENT PAGES (privacy, terms) ================================================================ */ diff --git a/static/css/tokens.css b/static/css/tokens.css index 01e3000..47242c5 100644 --- a/static/css/tokens.css +++ b/static/css/tokens.css @@ -1,88 +1,103 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Archivo:wght@500;600;700;800;900&family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700;800&display=swap'); :root { /* Core surfaces */ - --bg: #0a0a0d; - --surface: #111115; - --surface-raised:#16161c; - --surface-head: #18181f; - --surface-sunk: #0d0d11; - --field: #1a1a22; - --field-alt: #1c1c25; + --bg: #101419; + --surface: #171D25; + --surface-raised:#202835; + --surface-head: #202835; + --surface-sunk: #0D1116; + --surface-2: #202835; + --field: #1D2530; + --field-alt: #26313E; + --panel: #171D25; + --panel-hover: #202835; /* ---- borders / dividers ---- */ - --border: #22222b; - --border-strong: #2a2a34; - --border-hi: #32323d; - --divider: #191921; - --slash: #383843; + --border: #2B3542; + --border-strong: #3A4655; + --border-hi: #505D6E; + --divider: #25303B; + --slash: #3A4655; /* ---- text ---- */ - --text: #f4f2f9; - --text-strong: #edeaf5; - --text-body: #e8e6ef; - --text-2: #bdbbc8; - --num: #b2b0bb; - --muted: #8c8a96; - --muted-2: #82808c; - --faint: #7a7885; - --faint-2: #72707d; - --faintest: #64626d; - --faintest-2: #55535e; + --text: #F2F0ED; + --text-strong: #F2F0ED; + --text-body: #C7CED8; + --text-2: #C7CED8; + --num: #A1ACBA; + --muted: #9AA5B4; + --muted-2: #8793A3; + --faint: #6E7A8A; + --faint-2: #647080; + --faintest: #576272; + --faintest-2: #4B5666; - /* Brand accent */ - --accent: #9b8cf0; - --accent-ink: #12101e; - --accent-tint: #1f1d2e; - --accent-chip: #242137; - --accent-chip-bd:#383152; - --accent-a22: rgba(155,140,240,0.22); - --accent-a30: rgba(155,140,240,0.30); + /* Brand accent — muted purple */ + --accent: #9B8FE3; + --accent-ink: #0d0b18; + --accent-tint: #211D36; + --accent-chip: #292442; + --accent-chip-bd:#4D4581; + --accent-a22: rgba(155,143,227,0.22); + --accent-a30: rgba(155,143,227,0.30); + + /* Secondary accent — teal */ + --accent2: #35C6B8; + --accent2-ink: #04211e; + --accent2-tint: rgba(53,198,184,0.12); + --accent2-tint-bd:rgba(53,198,184,0.34); + + /* Tertiary accent — azure */ + --accent3: #5AA2F5; + --accent3-ink: #041427; + --accent3-tint: rgba(90,162,245,0.12); + --accent3-tint-bd:rgba(90,162,245,0.34); /* ---- semantic: poker value scale ---- */ - --pos: #6fc093; - --pos-bar: #41815a; - --pos-tint: rgba(111,192,147,0.12); - --pos-tint-bd: rgba(111,192,147,0.30); - --neg: #e0758a; - --neg-bar: #9e445a; - --neg-tint: rgba(224,117,138,0.13); - --neg-tint-bd: rgba(224,117,138,0.32); - --owes: #e8829a; - --owes-tint: rgba(232,130,154,0.15); - --owes-tint-bd: rgba(232,130,154,0.40); + --pos: #58D18E; + --pos-bar: #379562; + --pos-tint: rgba(88,209,142,0.12); + --pos-tint-bd: rgba(88,209,142,0.30); + --neg: #F06F7A; + --neg-bar: #AC4550; + --neg-tint: rgba(240,111,122,0.12); + --neg-tint-bd: rgba(240,111,122,0.30); + --owes: #F06F7A; + --owes-tint: rgba(240,111,122,0.14); + --owes-tint-bd: rgba(240,111,122,0.34); /* ---- semantic: cash-movement hues ---- */ - --warn: #e0b15c; - --warn-tint: rgba(224,177,92,0.13); - --warn-tint-bd: rgba(224,177,92,0.32); - --rolled: #8f93c2; + --warn: #E0B85C; + --warn-tint: rgba(224,184,92,0.12); + --warn-tint-bd: rgba(224,184,92,0.30); + --rolled: #8FA4BB; /* ---- medals ---- */ --rank-1: var(--accent); - --rank-2: #c2bcd0; - --rank-3: #a78bb0; + --rank-2: var(--accent2); + --rank-3: var(--accent3); /* ---- chart line palette (top-N order) ---- */ - --line-1: #9b8cf0; --line-2: #6fc093; --line-3: #e0b15c; - --line-4: #cf6f86; --line-5: #8f93c2; + --line-1: #9B8FE3; --line-2: #58D18E; --line-3: #E0B85C; + --line-4: #F06F7A; --line-5: #8FA4BB; /* Elevation */ - --shadow-sm: 0 1px 2px rgba(0,0,0,.28); - --shadow-md: 0 3px 12px rgba(0,0,0,.32), 0 1px 4px rgba(0,0,0,.24); - --shadow-lg: 0 10px 28px rgba(0,0,0,.38), 0 3px 10px rgba(0,0,0,.26); - --shadow-xl: 0 18px 48px rgba(0,0,0,.46), 0 6px 18px rgba(0,0,0,.30); + --shadow-sm: 0 1px 3px rgba(0,0,0,.38); + --shadow-md: 0 2px 10px rgba(0,0,0,.42), 0 1px 3px rgba(0,0,0,.28); + --shadow-lg: 0 8px 28px rgba(0,0,0,.46), 0 2px 8px rgba(0,0,0,.28); + --shadow-xl: 0 18px 48px rgba(0,0,0,.54), 0 4px 16px rgba(0,0,0,.32); /* ---- glass panel effect ---- */ - --glass-border: 1px solid rgba(255,255,255,.055); - --glass-bg: rgba(255,255,255,.02); + --glass-border: 1px solid var(--border); + --glass-bg: transparent; /* ---- spacing scale (4pt) ---- */ --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:24px; --s8:32px; --s10:40px; --s12:48px; - /* ---- radii ---- */ - --r-pill:5px; --r-sm:7px; --r-md:9px; --r-lg:12px; + /* ---- radii — industrial, minimal rounding ---- */ + --r-pill:4px; --r-sm:4px; --r-md:5px; --r-lg:6px; /* ---- containers ---- */ --w-public:1320px; @@ -91,6 +106,6 @@ --gutter: clamp(16px, 4vw, 40px); /* ---- Chart.js backward compat (read as raw strings by JS) ---- */ - --text-muted: #bdbbc8; - --line: #22222b; + --text-muted: #9AA5B4; + --line: #2B3542; } diff --git a/templates/landing.html b/templates/landing.html index abafec8..9e55204 100644 --- a/templates/landing.html +++ b/templates/landing.html @@ -81,433 +81,168 @@ {% block page_class %}page--landing{% endblock %} {% block content %} -
-
-

Home Poker Tracking

-

- Free poker - tracker - for home games. -

-

Track buy-ins, cashouts, player stats, profit and loss, settlements, and league leaderboards without rebuilding the same spreadsheet every game night.

-
- {% if is_logged_in %} - Open my leagues → - {% else %} - Start your league → - Sign in - {% endif %} +
+
+
+

Poker ledger & league tracker

+

Free poker ledger for home games.

+

Run a private poker league without rebuilding a spreadsheet after every session. Track players, buy-ins, cashouts, standings, and settlement history in one clean place.

+
+ {% if is_logged_in %} + Open my leagues + {% else %} + Create a league + Sign in + {% endif %} +
+
+ Free + Private by default + No payment processor + Append-only ledger +
-
- No fees - · - Append-only ledger - · - Poker stats - · - Private by default - {% if not is_logged_in %} - · - Search public leagues - {% endif %} -
-
-