/* ============================================================
   World Tour Tracker — V3 (Broadcast Control Deck)
   Editorial broadcast aesthetic — palette unified with /meta-weapons.
   Indigo + cyan primary, amber reserved for the WT brand badge only.
   ============================================================ */

:root {
  /* Surfaces — match meta-weapons body gradient family */
  --v2-bg:           #0a0c14;
  --v2-panel:        #141826;
  --v2-panel-raised: #1a1f30;
  --v2-panel-edge:   rgba(255, 255, 255, 0.05);
  --v2-sidebar:      #0c0e18;
  --v2-border:       rgba(255, 255, 255, 0.07);
  --v2-border-soft:  rgba(255, 255, 255, 0.04);

  /* Inks — match meta-weapons */
  --v2-ink:          #f5f7fb;
  --v2-dim:          #8c92a8;
  --v2-faint:        #5a6078;

  /* Primary accent — INDIGO (was amber) */
  --v2-indigo:       #818cf8;
  --v2-indigo-deep:  #6366f1;
  --v2-indigo-soft:  rgba(129, 140, 248, 0.12);
  --v2-indigo-glow:  rgba(129, 140, 248, 0.35);

  /* Secondary accent — CYAN (live indicators, hero gradients) */
  --v2-cyan:         #22d3ee;
  --v2-cyan-soft:    rgba(34, 211, 238, 0.12);
  --v2-cyan-glow:    rgba(34, 211, 238, 0.30);

  /* Brand amber — RESERVED for the WORLD TOUR mark + countdown only.
     Echoes the navbar logo gradient (#F5A623 → #FFD054) so the cockpit
     stays tied to TFL identity without amber flooding every section. */
  --v2-amber:        #f5a623;
  --v2-amber-warm:   #ffd054;
  --v2-amber-soft:   rgba(245, 166, 35, 0.12);
  --v2-amber-glow:   rgba(245, 166, 35, 0.30);

  /* Semantic colors */
  --v2-green:        #22c55e;          /* synced / on-pace / WIN */
  --v2-green-warm:   #4ade80;
  --v2-green-soft:   rgba(34, 197, 94, 0.12);
  --v2-green-glow:   rgba(34, 197, 94, 0.32);
  --v2-orange:       #f97316;          /* behind-pace warning (was crimson) */
  --v2-orange-soft:  rgba(249, 115, 22, 0.12);
  --v2-orange-glow:  rgba(249, 115, 22, 0.35);
  --v2-crimson:      #ef4444;          /* RESERVED — past season end / error only */
  --v2-crimson-warm: #f87171;
  --v2-crimson-glow: rgba(239, 68, 68, 0.35);

  /* Legacy electric alias — kept so charts.js + other consumers keep working */
  --v2-electric:     var(--v2-cyan);
  --v2-electric-glow:var(--v2-cyan-glow);

  /* Layered card surface */
  --v2-card-bg:      linear-gradient(180deg, #151a2a 0%, #10141f 100%);
  --v2-card-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 0 0 1px var(--v2-border),
    0 12px 28px -16px rgba(0, 0, 0, 0.6),
    0 4px 10px -6px rgba(0, 0, 0, 0.4);
  --v2-card-shadow-hover:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 0 0 1px rgba(255, 255, 255, 0.14),
    0 18px 40px -18px rgba(0, 0, 0, 0.7),
    0 6px 14px -6px rgba(0, 0, 0, 0.45);

  /* Focus rings — indigo (matches meta-weapons) */
  --v2-ring-amber:   0 0 0 3px rgba(129, 140, 248, 0.30);
  --v2-ring-ink:     0 0 0 3px rgba(245, 247, 251, 0.16);

  --v2-ease-emph:    cubic-bezier(0.16, 1, 0.3, 1);
  --v2-ease-out:     cubic-bezier(0.4, 0, 0.2, 1);

  --v2-font-headline: "Bebas Neue", "Inter", system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  --v2-font-display:  "Inter", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --v2-font-mono:     "JetBrains Mono", ui-monospace, "SFMono-Regular", "Menlo", monospace;
  --v2-font-body:     "Inter", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--v2-bg);
  color: var(--v2-ink);
  font-family: var(--v2-font-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Respect iOS notch / home-bar for fixed bottom elements */
  --v2-safe-bottom: env(safe-area-inset-bottom, 0px);
  /* The shared off-canvas nav slide-menu sits at right:-320px when closed.
     `clip` stops it from extending the document scrollWidth without creating
     a scroll container (which would break the sidebar's position: sticky). */
  overflow-x: clip;
}

/* Tabular figures everywhere numbers animate — prevents digit-width jitter */
.v2-points-input,
.v2-kpi-value,
.v2-rank-name,
.v2-rank-next,
.v2-pace-meta,
.v2-pace-meta .current,
.v2-today .value,
.v2-week-header .total,
.week-day-pts,
.v2-match-btn-pts,
.goal-pts,
.v2-ladder-pts,
.v2-mode-row .head .stats,
.v2-countdown-pill,
.v2-points-meta,
.v2-points-meta .pct {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

button { font-family: inherit; }
a { color: inherit; }

/* Universal focus ring — keyboard only, never on mouse */
:focus { outline: none; }
:focus-visible {
  outline: none;
  box-shadow: var(--v2-ring-amber);
  border-radius: 2px;
}

/* Atmospheric backdrop — indigo + cyan, matches meta-weapons body */
body::after {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none; z-index: 0;
  background:
    radial-gradient(ellipse 1200px 700px at 80% -10%, rgba(99, 102, 241, 0.10), transparent 60%),
    radial-gradient(ellipse 900px 600px at -10% 30%, rgba(34, 211, 238, 0.06), transparent 60%);
}

/* Subtle film-grain over the entire app shell */
body::before {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none; z-index: 1;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 0.95 0 0 0 0 0.90 0 0 0 0 0.80 0 0 0 0.18 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.28;
  mix-blend-mode: overlay;
}

/* ============================================================
   App layout — sticky left cockpit + live editorial right
   ============================================================ */

.v2-shell {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(340px, 400px) 1fr;
  min-height: calc(100vh - 54px);
}

/* Sidebar — sticky cockpit */
.v2-sidebar {
  position: sticky;
  top: 54px; /* below glass nav */
  align-self: start;
  background:
    radial-gradient(ellipse 600px 400px at 50% 0%, rgba(129, 140, 248, 0.05), transparent 70%),
    linear-gradient(180deg, #0e1224 0%, #0b0f1d 60%, #0a0d18 100%);
  border-right: 1px solid var(--v2-border);
  padding: 36px 28px;
  display: flex;
  flex-direction: column;
  gap: 32px;
  min-height: calc(100vh - 54px);
  z-index: 3;
  box-shadow: 1px 0 0 rgba(255, 255, 255, 0.02) inset;
}

/* Divider between numbered steps — edge-fading hairline so the sections
   read as separate chapters without feeling like framed boxes */
.v2-sidebar > section + section {
  position: relative;
  padding-top: 30px;
}
.v2-sidebar > section + section::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(129, 140, 248, 0.22) 18%,
    rgba(129, 140, 248, 0.28) 50%,
    rgba(34, 211, 238, 0.14) 82%,
    transparent 100%);
  pointer-events: none;
}

/* Vertical thread of light along the right edge of the sidebar */
.v2-sidebar::after {
  content: "";
  position: absolute;
  top: 24px; bottom: 24px; right: 0;
  width: 1px;
  background: linear-gradient(180deg,
    transparent 0%,
    rgba(129, 140, 248, 0.20) 25%,
    rgba(34, 211, 238, 0.10) 65%,
    transparent 100%);
  pointer-events: none;
}

/* Main editorial column */
.v2-main {
  position: relative;
  padding: 44px 48px 80px;
  display: flex;
  flex-direction: column;
  gap: 28px;
  min-width: 0; /* prevent grid overflow */
}

.v2-main::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 320px;
  background: radial-gradient(ellipse 800px 320px at 75% 0%, rgba(129, 140, 248, 0.08), transparent 70%);
  pointer-events: none;
  z-index: -1;
}

@media (max-width: 1100px) {
  .v2-main { padding: 36px 32px 64px; }
}

@media (max-width: 960px) {
  .v2-shell { grid-template-columns: 1fr; }
  .v2-sidebar {
    position: static;
    min-height: 0;
    border-right: none;
    border-bottom: 1px solid var(--v2-border);
    padding: 22px 18px 24px;
    gap: 18px;
  }
  .v2-sidebar::after { display: none; } /* sidebar right-edge thread irrelevant when stacked */
  .v2-main { padding: 28px 18px 96px; gap: 22px; } /* extra bottom for FAB clearance */
  .v2-masthead { padding-bottom: 12px; }
  .v2-masthead-title { font-size: 26px; }
  .v2-points-input { font-size: 38px; height: 60px; }
  .v2-points-step { height: 60px; width: 48px; }
  .v2-goal-pill { font-size: 16px; padding: 11px 11px; }
  .v2-match-btn { padding: 12px 12px; }
  .v2-match-btn-label { font-size: 21px; }
  .v2-headline { font-size: clamp(18px, 4.2vw, 26px); }
  .v2-headline-sub { font-size: 15px; margin-top: 14px; }
  .v2-eyebrow { font-size: 10.5px; letter-spacing: 2px; margin-bottom: 12px; }
  .v2-card,
  .roadmap-card,
  .pace-card,
  .v2-mode-split,
  .v2-ladder-card,
  .chart-card,
  .v2-week { padding: 18px 18px; }
  .v2-kpi { padding: 16px 16px; }
  .v2-kpi-value { font-size: 34px; }
  .v2-rank-name { font-size: 28px; }
  .v2-rank-glyph { width: 64px; height: 64px; }
  .v2-today { padding: 14px 16px; }
  .v2-today .value { font-size: 22px; }
  .v2-mode-split-title { font-size: 20px; }
  .week-day-bar { height: 60px; }
  .page-footer { padding: 24px 18px; }
}

@media (max-width: 480px) {
  .v2-sidebar { padding: 18px 14px 20px; }
  .v2-main { padding: 22px 14px calc(110px + var(--v2-safe-bottom, 0px)); }
  .v2-headline { font-size: clamp(16px, 4.2vw, 22px); }
  .v2-points-input { font-size: 34px; height: 56px; }
  .v2-points-step { height: 56px; width: 44px; }
  .v2-kpi { padding: 14px 14px; }
  .v2-kpi-value { font-size: 30px; }
  .v2-rank-name { font-size: 24px; }
  .v2-rank-glyph { width: 52px; height: 52px; }
  /* Segmented control: at 375px "QUICKPLAY QUICK CASH MANUAL" previously cramped.
     Smaller letter-spacing + tighter padding keeps all four tabs equal-width
     without overflow or awkward line-breaks. */
  .v2-mode-tab { padding: 8px 2px; font-size: 10px; letter-spacing: 0.2px; }
  .v2-card, .v2-week, .roadmap-card, .pace-card, .v2-mode-split, .v2-ladder-card, .chart-card { padding: 16px 16px; }

  /* Keep "AUG 20" on one line so the Finish By chip doesn't split awkwardly. */
  .v2-overdue-text { font-size: 26px; letter-spacing: 0.02em; }
  .v2-kpi-value.v2-overdue { font-size: 26px; gap: 8px; flex-wrap: nowrap; }
  .v2-overdue-mark { width: 24px; height: 24px; }

  /* Give the Today bar / Week bar a breathable corner on narrow screens */
  .v2-today { padding: 14px 14px; gap: 10px; }
  .v2-today .value { font-size: 22px; }
  .v2-today .sep { height: 28px; }

  /* Masthead — countdown pill shouldn't crowd the title */
  .v2-masthead { gap: 12px; }
  .v2-masthead-title { font-size: 26px; }
  .v2-countdown-pill { padding: 5px 9px; font-size: 10px; letter-spacing: 1.2px; }
}

/* Ask Scotty FAB — raise above the iOS home bar. */
#scotty-widget {
  bottom: calc(20px + var(--v2-safe-bottom, 0px)) !important;
}

/* On narrow mobile viewports, the cockpit's 2×2 match-button grid stretches
   full-width and collides with any bottom-anchored pill. Collapse the FAB to
   a tight circular icon so it no longer blocks primary tap zones, and keep
   it at bottom-right so the existing chat panel still anchors correctly. */
@media (max-width: 640px) {
  #scotty-widget {
    right: 12px !important;
    bottom: calc(12px + var(--v2-safe-bottom, 0px)) !important;
  }
  #scotty-widget #scotty-toggle {
    padding: 0 !important;
    width: 48px !important;
    height: 48px !important;
    border-radius: 50% !important;
    font-size: 0 !important;       /* hides inline "Ask Scotty" text */
    color: transparent !important;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    position: relative;
    box-shadow:
      0 6px 18px -4px rgba(245, 166, 35, 0.55),
      0 0 0 2px rgba(11, 16, 32, 0.9),
      0 0 0 3px rgba(245, 166, 35, 0.50) !important;
  }
  /* Chat bubble glyph — replaces the "ASK SCOTTY" label on mobile. */
  #scotty-widget #scotty-toggle::before {
    content: "";
    width: 22px; height: 22px;
    background-color: #0b1020;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M4 4h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-5l-4 4v-4H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm3 6h10v2H7v-2Zm0 4h7v2H7v-2Z'/></svg>") center / contain no-repeat;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M4 4h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-5l-4 4v-4H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm3 6h10v2H7v-2Zm0 4h7v2H7v-2Z'/></svg>") center / contain no-repeat;
  }
  /* Sibling label span (some builds) */
  #scotty-widget #scotty-label { display: none !important; }
}

/* ============================================================
   Sidebar — masthead
   ============================================================ */

.v2-masthead {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  padding-bottom: 16px;
  border-bottom: 2px solid var(--v2-ink);
}

.v2-masthead::after {
  content: "";
  position: absolute;
  left: 0; bottom: -2px;
  width: 48px;
  height: 2px;
  background: var(--v2-amber);
}

.v2-masthead-title {
  font-family: var(--v2-font-headline);
  font-size: 38px;
  font-weight: 400;
  letter-spacing: 0.02em;
  line-height: 0.9;
  margin: 0;
}

.v2-masthead-sub {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--v2-dim);
  margin-top: 6px;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.v2-masthead-sub::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--v2-cyan);
  box-shadow: 0 0 0 2px rgba(34, 211, 238, 0.20), 0 0 8px var(--v2-cyan);
  animation: livePulse 2.4s ease-in-out infinite;
}

@keyframes livePulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(34, 211, 238, 0.20), 0 0 8px var(--v2-cyan); }
  50%      { box-shadow: 0 0 0 6px rgba(34, 211, 238, 0.05), 0 0 12px var(--v2-cyan); }
}

.v2-countdown-pill {
  padding: 6px 11px;
  background: linear-gradient(180deg, #ffd166 0%, var(--v2-amber) 100%);
  color: #0b1020;
  font-family: var(--v2-font-mono);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.5px;
  border-radius: 2px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.4) inset,
    0 4px 12px -4px var(--v2-amber-glow);
}

/* ============================================================
   Sidebar — section labels
   ============================================================ */

.v2-section-label {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 2.5px;
  color: var(--v2-indigo);
  margin-bottom: 12px;
  font-weight: 700;
  text-transform: uppercase;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}

.v2-section-label > span:first-child {
  position: relative;
  padding-left: 14px;
}

.v2-section-label > span:first-child::before {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  width: 8px; height: 2px;
  background: var(--v2-indigo);
  transform: translateY(-50%);
  box-shadow: 0 0 8px rgba(129, 140, 248, 0.6);
}

.v2-section-label .meta {
  color: var(--v2-dim);
  letter-spacing: 1px;
  font-weight: 600;
  white-space: nowrap;
}

/* Sidebar — louder step labels so ①/②/③ read like section titles, not footnotes */
.v2-sidebar .v2-section-label {
  font-size: 14px;
  letter-spacing: 2px;
  margin-bottom: 14px;
}
.v2-sidebar .v2-section-label > span:first-child {
  padding-left: 16px;
}
.v2-sidebar .v2-section-label > span:first-child::before {
  width: 10px;
  height: 2px;
}
.v2-sidebar .v2-section-label .meta {
  font-size: 12px;
  letter-spacing: 1.2px;
}

/* ============================================================
   Sidebar — points input
   ============================================================ */

.v2-points-input-wrap {
  display: flex;
  align-items: stretch;
  background: linear-gradient(180deg, #0e1428 0%, #0a0f23 100%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 0 0 1px var(--v2-border),
    0 6px 18px -10px rgba(0, 0, 0, 0.6);
  transition: box-shadow 0.18s var(--v2-ease-out);
}

.v2-points-input-wrap:focus-within {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 0 0 1px var(--v2-indigo),
    0 0 0 4px rgba(129, 140, 248, 0.20),
    0 6px 18px -10px rgba(0, 0, 0, 0.6);
}

.v2-points-step {
  width: 52px; height: 68px;
  border: none;
  background: transparent;
  color: var(--v2-dim);
  font-size: 24px;
  font-weight: 400;
  cursor: pointer;
  transition: color 0.15s, background 0.15s, transform 0.08s;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.v2-points-step:hover {
  color: var(--v2-indigo);
  background: rgba(129, 140, 248, 0.08);
}

.v2-points-step:active {
  transform: scale(0.92);
  background: rgba(129, 140, 248, 0.14);
}

.v2-points-input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: var(--v2-ink);
  font-family: var(--v2-font-display);
  font-size: 44px;
  font-weight: 700;
  text-align: center;
  letter-spacing: 0.02em;
  width: 100%;
  height: 68px;
  -moz-appearance: textfield;
  caret-color: var(--v2-indigo);
}
.v2-points-input::-webkit-outer-spin-button,
.v2-points-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.v2-points-meta {
  margin-top: 10px;
  font-family: var(--v2-font-mono);
  font-size: 12px;
  letter-spacing: 1px;
  color: var(--v2-dim);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.v2-points-meta .pct {
  color: var(--v2-indigo);
  font-weight: 700;
  letter-spacing: 0.5px;
}

/* ============================================================
   Sidebar — goal pills
   ============================================================ */

.v2-goal-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}

.v2-goal-pill {
  position: relative;
  border: 1px solid var(--v2-border);
  background: linear-gradient(180deg, rgba(238, 242, 255, 0.02), transparent);
  color: var(--v2-ink);
  padding: 13px 12px;
  font-family: var(--v2-font-display);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  text-align: left;
  transition: border-color 0.15s var(--v2-ease-out),
              background 0.15s var(--v2-ease-out),
              transform 0.12s var(--v2-ease-out),
              color 0.15s var(--v2-ease-out),
              box-shadow 0.18s var(--v2-ease-out);
  overflow: hidden;
}

.v2-goal-pill::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--v2-indigo);
  opacity: 0;
  transition: opacity 0.15s var(--v2-ease-out);
}

.v2-goal-pill:hover {
  border-color: rgba(129, 140, 248, 0.35);
  background: rgba(129, 140, 248, 0.05);
  transform: translateY(-1px);
}

.v2-goal-pill:hover::before { opacity: 0.5; }

.v2-goal-pill:active { transform: translateY(0); }

.v2-goal-pill.active {
  border-color: transparent;
  background: linear-gradient(180deg, var(--v2-indigo) 0%, var(--v2-indigo-deep) 100%);
  color: #ffffff;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.30) inset,
    0 6px 18px -6px var(--v2-indigo-glow);
}

.v2-goal-pill.active::before { opacity: 0; }

.v2-goal-pill .goal-pts {
  display: block;
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 1px;
  font-weight: 600;
  opacity: 0.65;
  margin-top: 4px;
}

.v2-goal-pill.active .goal-pts { opacity: 0.85; }

/* "Other" link to open native goal select */
.v2-goal-other {
  display: block;
  margin-top: 10px;
  font-family: var(--v2-font-mono);
  font-size: 12px;
  letter-spacing: 1.4px;
  color: var(--v2-dim);
  background: none;
  border: none;
  padding: 4px 0;
  cursor: pointer;
  text-transform: uppercase;
  text-align: left;
  width: 100%;
}
.v2-goal-other:hover { color: var(--v2-ink); }

/* ─── Collapsed goal-summary row (default state) ─── */
.v2-goal-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 10px 12px;
  background: linear-gradient(180deg, rgba(238, 242, 255, 0.025), transparent);
  border: 1px solid var(--v2-border);
  border-radius: 2px;
  color: var(--v2-ink);
  font-family: var(--v2-font-display);
  font-size: 14px;
  letter-spacing: 0.02em;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s var(--v2-ease-out),
              background 0.15s var(--v2-ease-out);
}

.v2-goal-summary:hover {
  border-color: rgba(129, 140, 248, 0.35);
  background: rgba(129, 140, 248, 0.05);
}

.v2-goal-summary-label {
  font-family: var(--v2-font-mono);
  font-size: 10.5px;
  letter-spacing: 1.3px;
  color: var(--v2-dim);
  text-transform: uppercase;
}

.v2-goal-summary-name {
  font-weight: 700;
  color: var(--v2-indigo, #818cf8);
}

.v2-goal-summary-sep { color: var(--v2-dim); }

.v2-goal-summary-remain {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 0.4px;
  color: var(--v2-dim);
  flex: 1;
}

.v2-goal-summary-action {
  font-family: var(--v2-font-mono);
  font-size: 10.5px;
  letter-spacing: 1.3px;
  color: var(--v2-dim);
  text-transform: uppercase;
  margin-left: auto;
}

.v2-goal-summary:hover .v2-goal-summary-action { color: var(--v2-ink); }

/* Expanded state — hide summary, show grid + "Other tier" + late-start */
.v2-goal-section:not(.is-collapsed) .v2-goal-summary { display: none; }
.v2-goal-section.is-collapsed .v2-goal-expand { display: none; }

/* Stacked late-start toggle below "Other tier" */
.late-start-toggle { display: flex; }

/* Hidden native select powering the underlying tracker.js */
#goalSelect.v2-hidden {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0; pointer-events: none;
  left: -9999px;
}

/* ============================================================
   Sidebar — match logger
   ============================================================ */

.v2-mode-tabs {
  position: relative;
  display: flex;
  gap: 0;
  margin-bottom: 12px;
  padding: 4px;
  background: rgba(11, 16, 32, 0.6);
  border: 1px solid var(--v2-border-soft);
  border-radius: 4px;
}

.v2-mode-tab {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--v2-dim);
  padding: 9px 4px;
  cursor: pointer;
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 0.6px;
  font-weight: 700;
  text-transform: uppercase;
  white-space: nowrap;
  transition: background 0.18s var(--v2-ease-out),
              color 0.18s var(--v2-ease-out);
  border-radius: 2px;
  -webkit-tap-highlight-color: transparent;
}

.v2-mode-tab:hover { color: var(--v2-ink); }

.v2-mode-tab.active {
  background: linear-gradient(180deg, var(--v2-indigo) 0%, var(--v2-indigo-deep) 100%);
  color: #ffffff;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.25) inset,
    0 6px 14px -6px var(--v2-indigo-glow);
}

.v2-match-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}

.v2-match-grid.single { grid-template-columns: 1fr; }

.v2-match-btn {
  position: relative;
  border: 1px solid var(--v2-border);
  background: linear-gradient(180deg, rgba(238, 242, 255, 0.025), transparent);
  padding: 14px 14px;
  text-align: left;
  cursor: pointer;
  color: var(--v2-ink);
  transition: transform 0.1s var(--v2-ease-out),
              border-color 0.18s var(--v2-ease-out),
              background 0.18s var(--v2-ease-out),
              box-shadow 0.18s var(--v2-ease-out);
  font-family: var(--v2-font-body);
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
}

.v2-match-btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 100% 0%, rgba(129, 140, 248, 0.12), transparent 60%);
  opacity: 0;
  transition: opacity 0.2s var(--v2-ease-out);
  pointer-events: none;
}

.v2-match-btn:hover {
  border-color: rgba(129, 140, 248, 0.40);
  background: rgba(129, 140, 248, 0.05);
  transform: translateY(-1px);
}

.v2-match-btn:hover::after { opacity: 1; }

.v2-match-btn:active {
  transform: translateY(0) scale(0.98);
  transition-duration: 0.05s;
}

/* WIN — green primary (was loud crimson). Wins are positive; green reads
   as "match recorded successfully" which matches the actual semantic. */
.v2-match-btn.hero {
  border: 1px solid transparent;
  background: linear-gradient(180deg, var(--v2-green-warm) 0%, var(--v2-green) 100%);
  color: #06210f;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.35) inset,
    0 8px 22px -8px var(--v2-green-glow),
    0 0 0 1px rgba(34, 197, 94, 0.45);
}

.v2-match-btn.hero::after {
  background: radial-gradient(circle at 50% 0%, rgba(255, 255, 255, 0.22), transparent 65%);
  opacity: 0.9;
}

.v2-match-btn.hero:hover {
  background: linear-gradient(180deg, #5fec96 0%, #27d36a 100%);
  transform: translateY(-1px);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.4) inset,
    0 12px 28px -8px var(--v2-green-glow),
    0 0 0 1px rgba(34, 197, 94, 0.6);
}

.v2-match-btn.hero:active {
  transform: translateY(0) scale(0.98);
}

.v2-match-btn-pts {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 1.5px;
  opacity: 0.85;
  font-weight: 700;
}

.v2-match-btn.hero .v2-match-btn-pts { opacity: 0.95; }

.v2-match-btn-label {
  font-family: var(--v2-font-display);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: 0.02em;
  margin-top: 6px;
}

/* Manual entry */
.v2-manual {
  display: flex;
  gap: 6px;
}

.v2-manual-num {
  flex: 1;
  border: 1px solid var(--v2-border);
  background: linear-gradient(180deg, rgba(238, 242, 255, 0.025), transparent);
  color: var(--v2-ink);
  padding: 14px 4px;
  font-size: 20px;
  font-weight: 700;
  font-family: var(--v2-font-display);
  cursor: pointer;
  text-align: center;
  transition: background 0.18s var(--v2-ease-out),
              border-color 0.18s var(--v2-ease-out),
              transform 0.08s var(--v2-ease-out);
  -webkit-tap-highlight-color: transparent;
}

.v2-manual-num:hover {
  border-color: var(--v2-indigo);
  background: var(--v2-indigo-soft);
}

.v2-manual-num:active {
  transform: scale(0.96);
}

/* Undo */
.v2-undo {
  margin-top: 12px;
  border: 1px solid rgba(129, 140, 248, 0.35);
  background: rgba(129, 140, 248, 0.08);
  color: var(--v2-ink);
  padding: 12px;
  font-size: 11px;
  letter-spacing: 2px;
  font-family: var(--v2-font-mono);
  font-weight: 600;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.03) inset,
              0 2px 8px -4px rgba(129, 140, 248, 0.25);
  transition: color 0.18s var(--v2-ease-out),
              border-color 0.18s var(--v2-ease-out),
              background 0.18s var(--v2-ease-out),
              box-shadow 0.18s var(--v2-ease-out),
              transform 0.12s var(--v2-ease-out);
  -webkit-tap-highlight-color: transparent;
}

.v2-undo:hover {
  color: #ffffff;
  border-color: var(--v2-indigo);
  background: rgba(129, 140, 248, 0.18);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06) inset,
              0 4px 14px -4px var(--v2-indigo-glow);
}

.v2-undo:active {
  transform: scale(0.98);
  background: rgba(129, 140, 248, 0.22);
}

.v2-undo:focus-visible {
  outline: none;
  border-color: var(--v2-indigo);
  box-shadow: 0 0 0 2px rgba(129, 140, 248, 0.35),
              0 4px 14px -4px var(--v2-indigo-glow);
}

/* Sidebar footer — sync status */
.v2-sync {
  margin-top: auto;
  padding: 14px 12px;
  border: 1px solid var(--v2-border-soft);
  background: rgba(11, 16, 32, 0.4);
  font-family: var(--v2-font-mono);
  font-size: 10px;
  letter-spacing: 1.5px;
  color: var(--v2-dim);
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
}

.v2-sync .dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--v2-green);
  box-shadow:
    0 0 0 2px rgba(34, 197, 94, 0.20),
    0 0 12px rgba(34, 197, 94, 0.55);
  animation: syncPulse 2.4s ease-in-out infinite;
}

@keyframes syncPulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.20), 0 0 12px rgba(34, 197, 94, 0.55); }
  50%      { box-shadow: 0 0 0 6px rgba(34, 197, 94, 0.04), 0 0 14px rgba(34, 197, 94, 0.65); }
}

.v2-sync.anon .dot {
  background: var(--v2-dim);
  box-shadow: 0 0 0 2px rgba(238, 242, 255, 0.06);
  animation: none;
}

.v2-sync-action {
  margin-left: auto;
  background: rgba(129, 140, 248, 0.10);
  border: 1px solid rgba(129, 140, 248, 0.35);
  color: var(--v2-indigo);
  font: inherit;
  cursor: pointer;
  padding: 5px 10px;
  letter-spacing: 1.5px;
  transition: background 0.15s var(--v2-ease-out), color 0.15s var(--v2-ease-out);
  -webkit-tap-highlight-color: transparent;
}
.v2-sync-action:hover {
  color: #ffffff;
  background: var(--v2-indigo-deep);
  border-color: var(--v2-indigo-deep);
}

/* ============================================================
   Main — eyebrow + headline
   ============================================================ */

.v2-eyebrow {
  font-family: var(--v2-font-mono);
  font-size: 12px;
  letter-spacing: 2.5px;
  color: var(--v2-indigo);
  margin-bottom: 16px;
  text-transform: uppercase;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  /* Fade in just after the headline — staggered reveal gives the page a
     "broadcast opening sequence" quality instead of a flat drop-in. */
  animation: eyebrowFade 0.6s 0.05s var(--v2-ease-out) both;
}

.v2-eyebrow::before {
  content: "";
  width: 24px;
  height: 2px;
  background: linear-gradient(90deg, var(--v2-indigo), var(--v2-cyan));
  box-shadow: 0 0 10px rgba(129, 140, 248, 0.5);
}

@keyframes eyebrowFade {
  0%   { opacity: 0; transform: translate3d(-4px, 0, 0); }
  100% { opacity: 1; transform: translate3d(0, 0, 0); }
}

.v2-headline-sub {
  /* Pick up the same staggered reveal */
  animation: eyebrowFade 0.7s 0.18s var(--v2-ease-out) both;
}

.v2-headline {
  font-family: var(--v2-font-headline);
  font-size: clamp(36px, 4.8vw, 60px);
  font-weight: 400;
  letter-spacing: 0.02em;
  line-height: 1.15;
  margin: 0;
  text-wrap: pretty;
  text-transform: uppercase;
  color: var(--v2-dim);
  opacity: 0.85;
  /* Soft entrance so the headline feels alive on first paint */
  animation: headlineRise 0.7s var(--v2-ease-emph) both;
}

/* The seasonal headline strip sits at the top of the main column.
   Acts as the page-leading heading; the daily-target hero is the
   first content card below it. */
.v2-headline-strip {
  padding-top: 4px;
}

@keyframes headlineRise {
  0%   { opacity: 0; transform: translate3d(0, 8px, 0); }
  100% { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* "Behind / over" → orange (warm warning, was alarming crimson) */
.v2-headline .accent-crimson {
  color: var(--v2-orange);
  text-shadow: 0 0 30px rgba(249, 115, 22, 0.25);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* Goal name → meta-weapons hero treatment: indigo → cyan gradient text */
.v2-headline .accent-amber {
  background: linear-gradient(135deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 6px 22px rgba(129, 140, 248, 0.32));
  text-decoration: underline var(--v2-indigo) 4px;
  text-underline-offset: 10px;
  text-decoration-skip-ink: none;
}

/* Trailing sentence punctuation — keeps the period from absorbing the gradient
   underline, so the headline reads like a proper sentence. */
.v2-headline .dot {
  color: var(--v2-ink);
  -webkit-text-fill-color: var(--v2-ink);
  background: none;
  filter: none;
  text-decoration: none;
  margin-left: -0.04em; /* snug tight against the last glyph */
}

.v2-headline-sub {
  font-size: 14px;
  color: var(--v2-dim);
  line-height: 1.5;
  margin: 6px 0 0;
  max-width: 760px;
  opacity: 0.85;
}

/* ============================================================
   Hero row — Today's Target (left) + Current Rank (right).
   Two equal columns on desktop; stacks on tablet and below.
   ============================================================ */

.v2-hero-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  align-items: stretch;
}

/* Both children stretch to equal heights so the row reads as a unit;
   the rank-card's pace bar visually lines up with the daily-target's
   final path row when content lengths roughly match. */
.v2-hero-row > .v2-daily-target,
.v2-hero-row > .v2-rank-progress-card {
  margin: 0;
  height: 100%;
}

/* Stack on narrow viewports where 2 cards × 3 path rows × tier ticks
   would all squish into illegibility. The sidebar stays — only the
   right-column cards collapse to a single stack. */
@media (max-width: 1400px) {
  .v2-hero-row { grid-template-columns: 1fr; gap: 22px; }
}

/* — Half-width tightening: when daily-target sits in the hero row, its
     combo strings ("1 Win + 1 R1 KO") have less horizontal room than
     when the card was full-width. Drop padding and font sizes a notch
     and force the action onto one line so the layout stays tidy. — */
.v2-hero-row .v2-daily-target {
  padding: 24px 22px 22px;
}
.v2-hero-row .v2-dt-row {
  grid-template-columns: 88px 1fr auto;
  gap: 10px;
  padding: 10px 12px;
}
.v2-hero-row .v2-dt-row .mode {
  font-size: 11.5px;
  letter-spacing: 0.6px;
  white-space: nowrap;
}
.v2-hero-row .v2-dt-row .action {
  font-size: 14.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.v2-hero-row .v2-dt-row .total {
  font-size: 13.5px;
  white-space: nowrap;
}
.v2-hero-row .v2-dt-row .total .delta {
  display: block;
  margin-left: 0;
  margin-top: 1px;
  text-align: right;
}
.v2-hero-row .v2-dt-num {
  font-size: clamp(48px, 5.6vw, 76px);
}
.v2-hero-row .v2-dt-unit {
  font-size: clamp(17px, 2vw, 24px);
}

/* — Rank-card tier labels also tighten when sharing the row. The tier
     row is `repeat(6, 1fr)`; at half width "PLATINUM/DIAMOND/EMERALD"
     crowd. Drop one notch and trim letter-spacing. — */
.v2-hero-row .v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks {
  font-size: 10.5px !important;
  letter-spacing: 0.2px !important;
}
.v2-hero-row .v2-rank-progress-card {
  padding: 22px 22px 24px;
}

/* Below the hero-row breakpoint the cards stack and recover full width,
   so undo the tightening. */
@media (max-width: 1400px) {
  .v2-hero-row .v2-daily-target { padding: 28px 32px 24px; }
  .v2-hero-row .v2-dt-row {
    grid-template-columns: 110px 1fr auto;
    gap: 16px;
    padding: 12px 14px;
  }
  .v2-hero-row .v2-dt-row .mode { font-size: 12.5px; letter-spacing: 0.8px; }
  .v2-hero-row .v2-dt-row .action { font-size: 16px; white-space: normal; }
  .v2-hero-row .v2-dt-row .total { font-size: 15px; }
  .v2-hero-row .v2-dt-row .total .delta { display: inline; margin-left: 6px; }
  .v2-hero-row .v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks {
    font-size: 12px !important;
    letter-spacing: 0.4px !important;
  }
}

/* ============================================================
   Daily Target hero — the hero "can I stop playing yet?" answer.
   Replaces the slim "Today | Pts left today" strip and sits above
   the rank/pace card. Owns the most-asked question on the page.
   ============================================================ */

.v2-daily-target {
  background:
    radial-gradient(ellipse 700px 280px at 30% 0%, rgba(129, 140, 248, 0.10), transparent 70%),
    linear-gradient(180deg, rgba(129, 140, 248, 0.05) 0%, rgba(11, 16, 32, 0.6) 100%);
  border: 1px solid var(--v2-border);
  border-radius: 4px;
  padding: 28px 32px 24px;
  display: flex;
  flex-direction: column;
  gap: 22px;
  position: relative;
  overflow: hidden;
  animation: headlineRise 0.7s var(--v2-ease-emph) both;
}

/* Hairline accent across the top edge — keeps the block from feeling like
   another generic card and signals "this is the headline answer". */
.v2-daily-target::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg,
    transparent 0%,
    var(--v2-indigo) 20%,
    var(--v2-cyan) 60%,
    transparent 100%);
  opacity: 0.7;
}

.v2-dt-eyebrow {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 2.4px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--v2-indigo);
  margin-bottom: 8px;
}

.v2-dt-hero {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
  line-height: 1;
}

.v2-dt-num {
  font-family: var(--v2-font-display);
  font-size: clamp(56px, 7vw, 96px);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 0.9;
  background: linear-gradient(135deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 6px 22px rgba(129, 140, 248, 0.32));
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.v2-dt-unit {
  font-family: var(--v2-font-display);
  font-size: clamp(20px, 2.4vw, 30px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--v2-ink);
}

/* Done-for-today + goal-reached states */
.v2-dt-hero.done .v2-dt-num,
.v2-dt-hero.won .v2-dt-num {
  background: linear-gradient(135deg, #3fd79a 0%, #6aa6ff 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 6px 22px rgba(63, 215, 154, 0.32));
}

.v2-dt-bank {
  font-size: 13px;
  color: var(--v2-dim);
  margin: 0;
}
.v2-dt-bank strong {
  color: var(--v2-ink);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Paths section */
.v2-dt-paths-label {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--v2-dim);
  margin-bottom: 10px;
}

.v2-dt-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.v2-dt-row {
  display: grid;
  grid-template-columns: 110px 1fr auto;
  align-items: center;
  gap: 16px;
  padding: 12px 14px;
  background: rgba(238, 242, 255, 0.025);
  border: 1px solid var(--v2-border);
  border-radius: 3px;
  transition: background 0.2s var(--v2-ease-out), border-color 0.2s var(--v2-ease-out);
}

.v2-dt-row:hover {
  background: rgba(129, 140, 248, 0.06);
  border-color: rgba(129, 140, 248, 0.28);
}

.v2-dt-row .mode {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--v2-indigo);
}

.v2-dt-row .action {
  font-family: var(--v2-font-body);
  font-size: 15px;
  font-weight: 500;
  color: var(--v2-ink);
}

.v2-dt-row .total {
  font-family: var(--v2-font-mono);
  font-size: 14px;
  font-weight: 700;
  color: var(--v2-ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.v2-dt-row .total .delta {
  margin-left: 6px;
  font-size: 11px;
  color: var(--v2-dim);
  font-weight: 500;
}

@media (max-width: 720px) {
  .v2-daily-target { padding: 22px 18px 20px; gap: 18px; }
  .v2-dt-row { grid-template-columns: 90px 1fr auto; gap: 10px; padding: 10px 12px; }
  .v2-dt-row .action { font-size: 14px; }
  .v2-dt-row .mode { font-size: 10px; letter-spacing: 1.2px; }
}

.v2-headline-sub strong {
  color: var(--v2-ink);
  font-weight: 600;
  background: linear-gradient(180deg, transparent 65%, rgba(129, 140, 248, 0.22) 65%);
  padding: 0 2px;
}

/* ============================================================
   Main — pace bar + current rank
   ============================================================ */

.v2-pace-row {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 32px;
}

@media (max-width: 1100px) {
  .v2-pace-row { grid-template-columns: 1fr; gap: 24px; }
}

/* ─── Unified Rank + Progress card (Option B) ─── */
.v2-rank-progress-card {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 28px 30px;
}

.v2-rank-progress-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}

.v2-rank-progress-card .v2-rank-text { flex: 1; min-width: 0; }

/* Pace-bar adornment for the ticks strip (reuses existing selector) */
.v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks { margin-top: 6px; }

@media (max-width: 720px) {
  .v2-rank-progress-card { padding: 22px 20px; gap: 16px; }
  .v2-rank-progress-card .v2-rank-glyph { width: 56px; height: 56px; }
  .v2-rank-progress-card .v2-rank-name { font-size: 28px; }
}

/* ─── Hero sub-line chips (pace summary) ─── */
.v2-pace-chip {
  display: inline-block;
  padding: 2px 9px;
  font-family: var(--v2-font-mono);
  font-size: 10.5px;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  font-weight: 700;
  border-radius: 2px;
  border: 1px solid transparent;
}
.v2-pace-chip.is-on {
  color: var(--v2-cyan, #22d3ee);
  border-color: rgba(34, 211, 238, 0.35);
  background: rgba(34, 211, 238, 0.08);
}
.v2-pace-chip.is-behind {
  color: #ff8a5c;
  border-color: rgba(255, 138, 92, 0.35);
  background: rgba(255, 138, 92, 0.08);
}
.v2-pace-chip.is-ahead {
  color: #6ee7b7;
  border-color: rgba(110, 231, 183, 0.35);
  background: rgba(110, 231, 183, 0.08);
}

.v2-headline-sub .v2-sep {
  display: inline-block;
  margin: 0 4px;
  color: var(--v2-dim);
}

.v2-headline-sub .is-overdue { color: #ff8a5c; }

/* Hero accents for daily needed + date */
.v2-headline .accent-pace {
  color: var(--v2-cyan, #22d3ee);
  font-weight: 800;
}
.v2-headline .accent-date {
  color: var(--v2-ink, #eef2ff);
  border-bottom: 2px solid rgba(129, 140, 248, 0.5);
  padding-bottom: 1px;
}

.v2-card {
  position: relative;
  background: var(--v2-card-bg);
  padding: 24px 26px;
  box-shadow: var(--v2-card-shadow);
  transition: box-shadow 0.25s var(--v2-ease-out);
}

.v2-pace-card .v2-section-label { margin-bottom: 16px; }

.v2-pace-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 1.5px;
  color: var(--v2-dim);
  margin-bottom: 14px;
  font-weight: 700;
}

.v2-pace-meta .current {
  color: var(--v2-indigo);
  font-size: 13px;
}

.v2-pace-bar {
  position: relative;
  height: 14px;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.35) 0%, rgba(238, 242, 255, 0.06) 100%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 1px 2px rgba(0, 0, 0, 0.4) inset;
  border-radius: 1px;
  overflow: visible;
}

.v2-pace-bar .pace-marker-line {
  position: absolute;
  top: -8px; bottom: -8px;
  width: 2px;
  background: repeating-linear-gradient(
    180deg,
    var(--v2-dim) 0 4px,
    transparent 4px 7px
  );
  z-index: 2;
}

.v2-pace-bar .pace-marker-label {
  position: absolute;
  top: -24px;
  font-size: 10px;
  font-family: var(--v2-font-mono);
  color: var(--v2-dim);
  letter-spacing: 1.2px;
  font-weight: 700;
  transform: translateX(-50%);
  white-space: nowrap;
}

/* Goal marker — your finish line, distinct from the dashed dim-grey ON PACE.
   Amber matches the goal name color in the headline above ("Emerald IV"),
   so the bar visually echoes the page's goal-accent language. The small
   diamond pin sits just above the bar to read as a "pin / target", not as
   another data line. Solid + subtle glow vs. ON PACE's dashed-grey gives
   the two markers clearly different visual languages. */
.v2-pace-bar .goal-marker {
  position: absolute;
  top: -4px;
  bottom: -4px;
  width: 2px;
  background: var(--v2-amber);
  transform: translateX(-50%);
  box-shadow: 0 0 6px var(--v2-amber-glow);
  pointer-events: none;
  z-index: 2;
  opacity: 0.9;
}
.v2-pace-bar .goal-marker::before {
  content: "";
  position: absolute;
  top: -8px;
  left: 50%;
  width: 6px;
  height: 6px;
  background: var(--v2-amber);
  transform: translateX(-50%) rotate(45deg);
  box-shadow: 0 0 6px var(--v2-amber-glow);
  border-radius: 1px;
}
.v2-pace-bar .goal-marker[hidden] {
  display: none;
}

.v2-pace-bar .fill {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 0%;
  background: linear-gradient(90deg, var(--v2-indigo) 0%, var(--v2-indigo-deep) 50%, var(--v2-cyan) 100%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.30) inset,
    0 0 18px var(--v2-indigo-glow);
  transition: width 0.6s var(--v2-ease-emph),
              background 0.45s var(--v2-ease-out),
              box-shadow 0.45s var(--v2-ease-out);
}

/* State-aware pace fill — orange when behind pace, green when goal met.
   The color shift acts like a dashboard warning light instead of a silent bar. */
.v2-pace-bar.behind .fill {
  background: linear-gradient(90deg, var(--v2-orange) 0%, #fbbf24 100%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.30) inset,
    0 0 18px var(--v2-orange-glow);
}

.v2-pace-bar.behind .knob {
  box-shadow:
    0 0 0 1px var(--v2-orange),
    0 0 12px var(--v2-orange-glow),
    0 4px 12px rgba(0, 0, 0, 0.5);
}

.v2-pace-bar.met .fill {
  background: linear-gradient(90deg, var(--v2-green) 0%, var(--v2-green-warm) 100%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.30) inset,
    0 0 18px var(--v2-green-glow);
}

.v2-pace-bar.met .knob {
  box-shadow:
    0 0 0 1px var(--v2-green),
    0 0 14px var(--v2-green-glow),
    0 4px 12px rgba(0, 0, 0, 0.5);
}

/* Ahead of pace — lean the gradient harder toward cyan so the mood reads
   "moving fast, on a winning arc" without jumping to green (reserved for
   actually hitting the goal). */
.v2-pace-bar.ahead .fill {
  background: linear-gradient(90deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.30) inset,
    0 0 22px var(--v2-cyan-glow);
}

.v2-pace-bar.ahead .knob {
  box-shadow:
    0 0 0 1px var(--v2-cyan),
    0 0 14px var(--v2-cyan-glow),
    0 4px 12px rgba(0, 0, 0, 0.5);
}

/* Animated shimmer riding the pace fill */
.v2-pace-bar .fill::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent 0%, rgba(255, 255, 255, 0.25) 50%, transparent 100%);
  background-size: 200% 100%;
  animation: paceShimmer 2.4s ease-in-out infinite;
}

@keyframes paceShimmer {
  0%   { background-position: -100% 0; }
  100% { background-position:  200% 0; }
}

.v2-pace-bar .knob {
  position: absolute;
  top: 50%;
  width: 16px; height: 16px;
  background: var(--v2-ink);
  border: 2px solid var(--v2-bg);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  box-shadow:
    0 0 0 1px var(--v2-indigo),
    0 0 12px var(--v2-indigo-glow),
    0 4px 12px rgba(0, 0, 0, 0.5);
  transition: left 0.6s var(--v2-ease-emph);
  z-index: 3;
}

/* Current rank card */
.v2-rank-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}

.v2-rank-text {
  flex: 1;
  min-width: 0;
}

.v2-rank-text .v2-section-label { margin-bottom: 8px; }

.v2-rank-name {
  /* Inter 800 instead of the condensed display face — the rank name is the
     emotional payoff of this card and reads heavier/more "badge-like" in a
     wide heavy sans than in a narrow display face. */
  font-family: var(--v2-font-body);
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -0.005em;
  line-height: 1.1;
  text-transform: uppercase;
}

.v2-rank-next {
  font-size: 14px;
  color: var(--v2-dim);
  margin-top: 8px;
  letter-spacing: 0.01em;
}

.v2-rank-glyph {
  flex-shrink: 0;
  width: 84px; height: 84px;
  display: grid;
  place-items: center;
  background: radial-gradient(circle at 50% 30%, rgba(129, 140, 248, 0.18), transparent 65%);
  border-radius: 50%;
  position: relative;
}

/* Slow rotating conic halo — reads as "your current tier is live" rather than
   a static decoration. Respects reduced-motion via the global override. */
.v2-rank-glyph::before {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    rgba(129, 140, 248, 0.35),
    rgba(34, 211, 238, 0.20),
    rgba(129, 140, 248, 0.00) 55%,
    rgba(129, 140, 248, 0.35)
  );
  mask: radial-gradient(circle, transparent 60%, #000 62%);
  -webkit-mask: radial-gradient(circle, transparent 60%, #000 62%);
  opacity: 0.7;
  animation: rankHaloSpin 9s linear infinite;
  pointer-events: none;
}

@keyframes rankHaloSpin {
  to { transform: rotate(360deg); }
}

/* ============================================================
   Main — KPI strip
   ============================================================ */

.v2-kpi-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
}

@media (max-width: 900px) {
  .v2-kpi-strip { grid-template-columns: repeat(2, 1fr); }
}

.v2-kpi {
  position: relative;
  background: var(--v2-card-bg);
  padding: 20px 22px;
  box-shadow: var(--v2-card-shadow);
  transition: box-shadow 0.25s var(--v2-ease-out), transform 0.25s var(--v2-ease-out);
  overflow: hidden;
}

.v2-kpi::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: transparent;
  transition: background 0.25s var(--v2-ease-out);
}

/* First KPI gets the hero indigo accent — "Daily Needed" is the most actionable KPI */
.v2-kpi:first-child::before {
  background: linear-gradient(90deg, var(--v2-indigo) 0%, transparent 70%);
}

.v2-kpi:hover {
  box-shadow: var(--v2-card-shadow-hover);
  transform: translateY(-1px);
}

.v2-kpi-label {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--v2-dim);
  margin-bottom: 12px;
  text-transform: uppercase;
  font-weight: 700;
}

.v2-kpi-value {
  font-family: var(--v2-font-display);
  font-size: 42px;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1;
  color: var(--v2-ink);
}

/* `.amber` class is preserved for the legacy tracker.js hooks but renders indigo */
.v2-kpi-value.amber {
  color: var(--v2-indigo);
  text-shadow: 0 0 24px rgba(129, 140, 248, 0.30);
}

.v2-kpi-sub {
  font-size: 13px;
  color: var(--v2-dim);
  margin-top: 10px;
  min-height: 16px;
  letter-spacing: 0.01em;
}

.v2-kpi-sub.positive { color: var(--v2-green); font-weight: 600; }
.v2-kpi-sub.negative { color: var(--v2-orange); font-weight: 600; }

/* Every KPI gets a subtle accent on hover — first card keeps its static hero
   indigo so the eye still has an anchor point. */
.v2-kpi:not(:first-child):hover::before {
  background: linear-gradient(90deg, var(--v2-indigo) 0%, transparent 70%);
}

/* "Finish By" overdue state — SVG warning glyph wrapped in a small chip.
   Replaces the raw ❌ emoji injected by the shared tracker engine, so the
   editorial aesthetic stays intact on the v3 surface. */
.v2-kpi-value.v2-overdue {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--v2-orange);
  text-shadow: 0 0 22px rgba(249, 115, 22, 0.25);
}

.v2-overdue-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px; height: 28px;
  color: var(--v2-orange);
  background: var(--v2-orange-soft);
  border-radius: 4px;
  box-shadow:
    0 0 0 1px rgba(249, 115, 22, 0.40),
    0 0 14px -4px var(--v2-orange-glow);
  flex-shrink: 0;
}

.v2-overdue-mark svg { display: block; }

.v2-overdue-text {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ============================================================
   Today + Week strips
   ============================================================ */

.v2-today {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 18px;
  background: var(--v2-card-bg);
  padding: 18px 24px;
  box-shadow: var(--v2-card-shadow);
  transition: box-shadow 0.3s var(--v2-ease-out);
}

.v2-today .group {
  display: flex;
  align-items: baseline;
  gap: 10px;
  white-space: nowrap;
}

.v2-today .group.right { justify-content: flex-end; }

.v2-today .label {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--v2-dim);
  font-weight: 700;
}

.v2-today .value {
  font-family: var(--v2-font-display);
  font-size: 28px;
  font-weight: 700;
  color: var(--v2-ink);
  letter-spacing: 0.02em;
}

.v2-today .value.green {
  color: var(--v2-green);
  text-shadow: 0 0 18px var(--v2-green-glow);
}

/* Green at zero is misleading — dim until there's actually a gain today. */
.v2-today .value.green.zero {
  color: var(--v2-dim);
  text-shadow: none;
}

.v2-today .sep {
  height: 32px;
  width: 1px;
  background: linear-gradient(180deg, transparent 0%, var(--v2-border) 50%, transparent 100%);
}

.v2-today.done {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.04) inset,
    0 0 0 1px rgba(34, 197, 94, 0.45),
    0 12px 28px -16px var(--v2-green-glow),
    0 4px 10px -6px rgba(0, 0, 0, 0.4);
}

/* Week bar — 7 vertical sparkbars */
.v2-week {
  background: var(--v2-card-bg);
  padding: 24px 26px;
  box-shadow: var(--v2-card-shadow);
}

.v2-week-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 16px;
}

.v2-week-header .title {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 2.5px;
  color: var(--v2-indigo);
  text-transform: uppercase;
  font-weight: 700;
}

.v2-week-header .total {
  font-family: var(--v2-font-display);
  font-size: 20px;
  font-weight: 700;
  color: var(--v2-ink);
  letter-spacing: 0.02em;
}

.week-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 8px;
  align-items: end;
}

.week-day {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  position: relative;
}

.week-day.today .week-day-label { color: var(--v2-indigo); }

.week-day-label {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 1.4px;
  color: var(--v2-dim);
  text-transform: uppercase;
  font-weight: 700;
  order: 3;
}

.week-day-bar {
  width: 100%;
  height: 72px;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.25), rgba(238, 242, 255, 0.04));
  position: relative;
  overflow: hidden;
  order: 2;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3) inset;
}

/* Empty-day bars get a gentle ghost pattern so the week doesn't read as broken
   on a fresh account. The pattern is more texture than content. */
.week-day.empty .week-day-bar {
  background:
    repeating-linear-gradient(
      135deg,
      rgba(255, 255, 255, 0.025) 0 6px,
      transparent 6px 12px
    ),
    linear-gradient(180deg, rgba(0, 0, 0, 0.25), rgba(238, 242, 255, 0.04));
}

.week-day-bar::before {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: var(--week-goal-line, 100%);
  height: 1px;
  background: rgba(129, 140, 248, 0.45);
  box-shadow: 0 0 6px rgba(129, 140, 248, 0.30);
  z-index: 1;
}

.week-day-fill {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  background: linear-gradient(180deg, var(--v2-indigo) 0%, var(--v2-indigo-deep) 100%);
  box-shadow: 0 0 8px var(--v2-indigo-glow);
  transition: height 0.6s var(--v2-ease-emph);
}

/* Met goal — graduates to green (semantic: "you cleared today's pace") */
.week-day-fill.met {
  background: linear-gradient(180deg, var(--v2-green-warm) 0%, var(--v2-green) 100%);
  box-shadow: 0 0 10px var(--v2-green-glow);
}

.week-day.today .week-day-bar {
  outline: 1px solid rgba(129, 140, 248, 0.40);
  outline-offset: 0;
}

.week-day-pts {
  font-family: var(--v2-font-mono);
  font-size: 12px;
  font-weight: 700;
  color: var(--v2-ink);
  order: 1;
}

.week-day.empty .week-day-pts { color: var(--v2-faint); font-weight: 400; }

/* ============================================================
   Roadmap + Pace Summary row
   ============================================================ */

.v2-progress-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
}

@media (max-width: 1400px) {
  .v2-progress-row { grid-template-columns: 1fr; }
}

.roadmap-card,
.pace-card {
  background: var(--v2-card-bg);
  padding: 24px 26px;
  box-shadow: var(--v2-card-shadow);
}

.pace-card { display: flex; flex-direction: column; gap: 18px; }

.pace-status {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 14px;
  align-items: center;
}

.pace-icon {
  grid-row: 1 / span 2;
  font-size: 26px;
  line-height: 1;
}

.pace-text {
  font-family: var(--v2-font-display);
  font-size: 28px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--v2-ink);
}

.pace-text.ahead { color: var(--v2-green); }
.pace-text.behind { color: var(--v2-orange); }

.pace-sub {
  font-family: var(--v2-font-body);
  font-size: 14px;
  color: var(--v2-dim);
  letter-spacing: 0.01em;
}

.pace-details {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pace-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 8px 0;
  border-top: 1px solid var(--v2-border-soft);
}

.pace-row:first-child { border-top: none; }

.pace-row-label {
  font-family: var(--v2-font-mono);
  font-size: 12px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  color: var(--v2-dim);
}

.pace-row-value {
  font-family: var(--v2-font-display);
  font-size: 20px;
  letter-spacing: 0.02em;
  color: var(--v2-ink);
}

.roadmap-header {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 2.5px;
  color: var(--v2-indigo);
  text-transform: uppercase;
  font-weight: 700;
  margin-bottom: 14px;
}

.roadmap-track {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.roadmap-row {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid var(--v2-border-soft);
  background: linear-gradient(180deg, rgba(238, 242, 255, 0.025), transparent);
  transition: border-color 0.18s var(--v2-ease-out), background 0.18s var(--v2-ease-out);
}

.roadmap-row:hover {
  border-color: rgba(129, 140, 248, 0.30);
  background: linear-gradient(180deg, rgba(129, 140, 248, 0.05), transparent);
}

.roadmap-row.goal {
  border: 1px solid var(--v2-indigo);
  background: linear-gradient(180deg, rgba(129, 140, 248, 0.18), rgba(129, 140, 248, 0.06));
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    0 0 18px -6px var(--v2-indigo-glow);
}

.roadmap-pip {
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 2px solid currentColor;
  background: rgba(0, 0, 0, 0.4);
}

.roadmap-info { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.roadmap-name { font-family: var(--v2-font-display); font-weight: 700; font-size: 17px; letter-spacing: 0.02em; color: var(--v2-ink); }
.roadmap-detail { font-family: var(--v2-font-mono); font-size: 12px; color: var(--v2-dim); letter-spacing: 0.6px; }

.roadmap-skip {
  font-family: var(--v2-font-mono);
  font-size: 12px;
  color: var(--v2-dim);
  text-align: center;
  padding: 4px 0;
  letter-spacing: 1.2px;
}

.roadmap-done {
  font-family: var(--v2-font-display);
  font-size: 18px;
  color: var(--v2-green);
  text-align: center;
  padding: 14px 0;
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* ============================================================
   Charts section (logged-in)
   ============================================================ */

.charts-section {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.charts-section .section-title {
  font-family: var(--v2-font-mono);
  font-size: 12px;
  letter-spacing: 2.5px;
  color: var(--v2-indigo);
  text-transform: uppercase;
  font-weight: 700;
}

.charts-section .section-title span { color: var(--v2-cyan); }

.chart-card {
  background: var(--v2-card-bg);
  padding: 24px 26px;
  box-shadow: var(--v2-card-shadow);
}

.chart-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 14px;
}

.chart-title {
  font-family: var(--v2-font-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.chart-badge {
  font-family: var(--v2-font-mono);
  font-size: 13px;
  font-weight: 700;
  color: var(--v2-indigo);
  letter-spacing: 1px;
}

.chart-caption {
  margin: -6px 0 14px;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--v2-text-muted, rgba(229, 231, 235, 0.66));
  letter-spacing: 0.01em;
}

.chart-canvas-wrapper {
  position: relative;
  width: 100%;
  height: 280px;
}

@media (max-width: 760px) {
  .chart-canvas-wrapper { height: 220px; }
}

/* Charts teaser for anon users */
.charts-teaser {
  position: relative;
  background: var(--v2-card-bg);
  padding: 44px 28px;
  text-align: center;
  overflow: hidden;
  box-shadow: var(--v2-card-shadow);
  border-top: 1px solid rgba(129, 140, 248, 0.18);
}

/* Faint grid on the teaser — references the "broadcast" graph aesthetic
   without needing any real data to display. */
.charts-teaser::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(129, 140, 248, 0.06) 1px, transparent 1px),
    linear-gradient(90deg, rgba(129, 140, 248, 0.06) 1px, transparent 1px);
  background-size: 32px 32px;
  opacity: 0.6;
  mask-image: radial-gradient(ellipse at center, #000 40%, transparent 80%);
  -webkit-mask-image: radial-gradient(ellipse at center, #000 40%, transparent 80%);
  pointer-events: none;
}

.charts-teaser-bg {
  position: absolute; inset: 0;
  background:
    radial-gradient(circle at 20% 20%, rgba(129, 140, 248, 0.14), transparent 55%),
    radial-gradient(circle at 80% 80%, rgba(34, 211, 238, 0.10), transparent 55%),
    radial-gradient(circle at 50% 50%, rgba(34, 197, 94, 0.05), transparent 70%);
  pointer-events: none;
  animation: teaserDrift 16s ease-in-out infinite alternate;
}

@keyframes teaserDrift {
  0%   { transform: translate(-2%, 0); }
  100% { transform: translate(2%, 1%); }
}

.charts-teaser-content { position: relative; }

.charts-teaser h3 {
  font-family: var(--v2-font-display);
  font-size: 28px;
  letter-spacing: 0.02em;
  margin: 0 0 14px;
  background: linear-gradient(135deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  text-transform: uppercase;
  filter: drop-shadow(0 6px 22px rgba(129, 140, 248, 0.32));
}

.charts-teaser p {
  color: var(--v2-dim);
  font-size: 15px;
  margin: 0 0 24px;
  line-height: 1.6;
}

/* ============================================================
   Mode split + Ladder row
   ============================================================ */

.v2-bottom-row {
  display: grid;
  grid-template-columns: 1fr 1.6fr;
  gap: 28px;
}

@media (max-width: 1200px) {
  .v2-bottom-row { grid-template-columns: 1fr; }
}

/* Mode split */
.v2-mode-split {
  background: var(--v2-card-bg);
  padding: 24px 26px;
  box-shadow: var(--v2-card-shadow);
}

.v2-mode-split-title {
  font-family: var(--v2-font-display);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: 0.02em;
  margin: 4px 0 18px;
}

.v2-mode-row { margin-bottom: 14px; }
.v2-mode-row:last-child { margin-bottom: 0; }

.v2-mode-row .head {
  display: flex;
  justify-content: space-between;
  font-family: var(--v2-font-display);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-bottom: 8px;
}

.v2-mode-row .head .stats {
  font-family: var(--v2-font-mono);
  font-size: 13px;
  color: var(--v2-dim);
  letter-spacing: 0.6px;
}

.v2-mode-row .bar {
  height: 6px;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.3), rgba(238, 242, 255, 0.05));
  position: relative;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.25) inset;
}

.v2-mode-row .bar > .fill {
  height: 100%;
  background: linear-gradient(90deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  box-shadow: 0 0 8px var(--v2-indigo-glow);
  transition: width 0.6s var(--v2-ease-emph);
}

.v2-mode-row.idx-1 .fill {
  background: linear-gradient(90deg, var(--v2-ink), rgba(238, 242, 255, 0.7));
  box-shadow: none;
}
.v2-mode-row.idx-2 .fill {
  background: var(--v2-dim);
  box-shadow: none;
}
.v2-mode-row.idx-3 .fill {
  background: var(--v2-faint);
  box-shadow: none;
}

.v2-mode-empty {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 1.2px;
  color: var(--v2-dim);
  padding: 22px 16px;
  text-align: center;
  border: 1px dashed rgba(129, 140, 248, 0.22);
  border-radius: 2px;
  line-height: 1.7;
  background: rgba(129, 140, 248, 0.03);
}

/* Ladder — 6 abstract glyph cards */
.v2-ladder-card {
  background: var(--v2-card-bg);
  padding: 24px 26px;
  box-shadow: var(--v2-card-shadow);
}

.v2-ladder {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
}

@media (max-width: 720px) {
  .v2-ladder { grid-template-columns: repeat(3, 1fr); }
}

.v2-ladder-cell {
  position: relative;
  padding: 16px 8px 14px;
  text-align: center;
  border: 1px solid var(--v2-border-soft);
  background: linear-gradient(180deg, rgba(238, 242, 255, 0.025), transparent);
  opacity: 0.45;
  transition: opacity 0.25s var(--v2-ease-out),
              border-color 0.25s var(--v2-ease-out),
              background 0.25s var(--v2-ease-out),
              transform 0.25s var(--v2-ease-out),
              box-shadow 0.25s var(--v2-ease-out);
  text-transform: uppercase;
}

.v2-ladder-cell.passed {
  opacity: 1;
  border-color: var(--v2-border);
}

.v2-ladder-cell.current {
  opacity: 1;
  border: 1px solid var(--v2-indigo);
  background: linear-gradient(180deg, rgba(129, 140, 248, 0.20), rgba(129, 140, 248, 0.04));
  transform: translateY(-2px);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 0 0 3px rgba(129, 140, 248, 0.18),
    0 12px 24px -10px var(--v2-indigo-glow);
  animation: ladderCurrentPulse 3.2s ease-in-out infinite;
}

@keyframes ladderCurrentPulse {
  0%, 100% {
    box-shadow:
      0 1px 0 rgba(255, 255, 255, 0.06) inset,
      0 0 0 3px rgba(129, 140, 248, 0.18),
      0 12px 24px -10px var(--v2-indigo-glow);
  }
  50% {
    box-shadow:
      0 1px 0 rgba(255, 255, 255, 0.08) inset,
      0 0 0 3px rgba(129, 140, 248, 0.30),
      0 16px 32px -10px var(--v2-indigo-glow);
  }
}

.v2-ladder-cell.current::before {
  content: "▾";
  position: absolute;
  top: -10px; left: 50%;
  transform: translateX(-50%);
  color: var(--v2-indigo);
  font-size: 14px;
  text-shadow: 0 0 8px var(--v2-indigo-glow);
}

/* Passed ladder cells pick up a gentle left border-light — like a filled
   progress tick across the tier band. */
.v2-ladder-cell.passed:not(.current)::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--v2-indigo) 0%, transparent 70%);
  opacity: 0.6;
}

.v2-ladder-glyph {
  width: 40px; height: 40px;
  margin: 0 auto 10px;
  display: block;
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.4));
}

.v2-ladder-name {
  font-family: var(--v2-font-display);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.v2-ladder-pts {
  font-family: var(--v2-font-mono);
  font-size: 11px;
  letter-spacing: 1px;
  color: var(--v2-dim);
  margin-top: 4px;
  font-weight: 700;
}

/* ============================================================
   Late-start toggle
   ============================================================ */

.late-start-toggle {
  margin-top: 6px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--v2-font-mono);
  font-size: 10px;
  letter-spacing: 1.4px;
  color: var(--v2-dim);
  text-decoration: none;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.12s;
}
.late-start-toggle:hover { color: var(--v2-ink); }

.late-start-arrow {
  display: inline-block;
  font-size: 8px;
  transition: transform 0.18s;
}

.late-start-toggle.open .late-start-arrow { transform: rotate(90deg); }

.late-start-container {
  display: none;
  margin-top: 8px;
}
.late-start-container.show { display: block; }

.late-start-inner {
  display: flex;
  gap: 6px;
  align-items: center;
}

.late-start-date {
  flex: 1;
  background: var(--v2-panel);
  border: 1px solid var(--v2-border);
  color: var(--v2-ink);
  font-family: var(--v2-font-body);
  font-size: 12px;
  padding: 8px 10px;
  outline: none;
  color-scheme: dark;
}

.late-start-date:focus { border-color: var(--v2-indigo); }

.late-start-reset {
  background: transparent;
  border: 1px solid var(--v2-border);
  color: var(--v2-dim);
  font-family: var(--v2-font-mono);
  font-size: 10px;
  letter-spacing: 1px;
  padding: 8px 10px;
  cursor: pointer;
  text-transform: uppercase;
  display: none;
}

.late-start-reset:hover { color: var(--v2-ink); border-color: var(--v2-indigo); }

/* ============================================================
   Notification + footer + last-updated
   ============================================================ */

.notification {
  position: fixed;
  top: 70px;
  right: 20px;
  background: linear-gradient(180deg, #1a1f30 0%, #141826 100%);
  color: var(--v2-ink);
  padding: 14px 20px;
  border-radius: 4px;
  font-family: var(--v2-font-display);
  font-weight: 600;
  font-size: 16px;
  letter-spacing: 0.02em;
  z-index: 9999;
  transform: translateY(-180%);
  opacity: 0;
  transition:
    transform 0.4s var(--v2-ease-emph),
    opacity 0.3s var(--v2-ease-out);
  max-width: 360px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    0 0 0 1px var(--v2-indigo),
    0 12px 32px -6px rgba(0, 0, 0, 0.5),
    0 0 24px -6px var(--v2-indigo-glow);
}

.notification.show { transform: translateY(0); opacity: 1; }

.notification.error {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    0 0 0 1px var(--v2-crimson),
    0 12px 32px -6px rgba(0, 0, 0, 0.5),
    0 0 24px -6px var(--v2-crimson-glow);
}
.notification.success {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    0 0 0 1px var(--v2-green),
    0 12px 32px -6px rgba(0, 0, 0, 0.5),
    0 0 24px -6px var(--v2-green-glow);
}

.last-updated {
  position: fixed;
  bottom: 12px;
  left: 12px;
  font-family: var(--v2-font-mono);
  font-size: 9px;
  letter-spacing: 1px;
  color: var(--v2-faint);
  z-index: 5;
  pointer-events: none;
}

.page-footer {
  background: var(--v2-sidebar);
  border-top: 1px solid var(--v2-border);
  color: var(--v2-dim);
  padding: 32px 48px;
  text-align: center;
  font-size: 13px;
  position: relative;
  z-index: 2;
}

.page-footer p { margin: 6px 0; }
.page-footer a { color: var(--v2-amber); text-decoration: none; }
.page-footer a:hover { color: var(--v2-ink); }

.footer-disclaimer { font-size: 11px; color: var(--v2-faint); }
.footer-tip { font-size: 12px; }

.footer-links {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 18px;
  margin-top: 16px;
  font-family: var(--v2-font-mono);
  font-size: 10px;
  letter-spacing: 1.4px;
  text-transform: uppercase;
}

.footer-links a.feedback { color: var(--v2-electric); }

/* ============================================================
   First-time overlay
   ============================================================ */

.first-time-overlay {
  position: fixed;
  inset: 0;
  background: rgba(11, 16, 32, 0.92);
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  backdrop-filter: blur(6px);
}

.first-time-content {
  background: var(--v2-panel);
  border: 1px solid var(--v2-border);
  padding: 32px;
  max-width: 440px;
  width: 100%;
}

.first-time-title {
  font-family: var(--v2-font-display);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.8px;
  margin: 0 0 12px;
  background: linear-gradient(135deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.first-time-step {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin-bottom: 18px;
}

.first-time-step-number {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(180deg, var(--v2-indigo) 0%, var(--v2-indigo-deep) 100%);
  color: #ffffff;
  font-family: var(--v2-font-display);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 12px -4px var(--v2-indigo-glow);
}

.first-time-step-text {
  flex: 1;
  color: var(--v2-dim);
  font-size: 14px;
  line-height: 1.5;
}

.first-time-step-text strong { color: var(--v2-indigo); }

.first-time-button {
  width: 100%;
  border: none;
  background: linear-gradient(180deg, var(--v2-indigo) 0%, var(--v2-indigo-deep) 100%);
  color: #fff;
  padding: 14px;
  font-family: var(--v2-font-display);
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.4px;
  cursor: pointer;
  margin-top: 8px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.20) inset,
    0 8px 22px -8px var(--v2-indigo-glow);
  transition: filter 0.18s var(--v2-ease-out);
}

.first-time-button:hover { filter: brightness(1.1); }

/* Discord button (anon top-right) */
.discord-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: #5865F2;
  color: #fff;
  border: none;
  padding: 8px 14px;
  font-family: var(--v2-font-display);
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
  letter-spacing: 0.2px;
  transition: background 0.12s;
}
.discord-btn:hover { background: #4752c4; }

/* Floating points juice — green to match the WIN button reward semantic */
.float-points {
  position: absolute;
  font-family: var(--v2-font-display);
  font-size: 24px;
  font-weight: 700;
  color: var(--v2-green-warm);
  pointer-events: none;
  animation: floatUp 950ms var(--v2-ease-emph) forwards;
  z-index: 10;
  text-shadow:
    0 0 14px rgba(74, 222, 128, 0.7),
    0 2px 6px rgba(0, 0, 0, 0.5);
  letter-spacing: 0.02em;
}

@keyframes floatUp {
  0%   { opacity: 0; transform: translateY(4px) scale(0.85); }
  18%  { opacity: 1; transform: translateY(0) scale(1); }
  100% { opacity: 0; transform: translateY(-54px) scale(1); }
}

/* Skeleton loading state */
.skeleton {
  position: relative;
  color: transparent !important;
  background: linear-gradient(90deg,
    rgba(255, 255, 255, 0.04) 0%,
    rgba(129, 140, 248, 0.10) 50%,
    rgba(255, 255, 255, 0.04) 100%);
  background-size: 200% 100%;
  animation: skeletonShine 1.6s ease-in-out infinite;
  border-radius: 2px;
}

@keyframes skeletonShine {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Confetti for milestones */
.confetti {
  position: fixed;
  top: -10px;
  width: 10px;
  height: 10px;
  background: var(--v2-indigo);
  z-index: 9998;
  animation: confettiFall linear forwards;
  pointer-events: none;
}

.confetti.circle { border-radius: 50%; }
.confetti.strip { width: 4px; height: 14px; }

@keyframes confettiFall {
  to {
    transform: translateY(100vh) rotate(720deg);
    opacity: 0;
  }
}

/* Milestone popup */
.milestone-popup {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: linear-gradient(180deg, #1a1f30 0%, #10141f 100%);
  padding: 36px 40px;
  z-index: 9999;
  text-align: center;
  max-width: 380px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.08) inset,
    0 0 0 1px var(--v2-indigo),
    0 0 0 4px rgba(129, 140, 248, 0.20),
    0 24px 60px -10px rgba(0, 0, 0, 0.7),
    0 0 60px -10px var(--v2-indigo-glow);
  animation: milestonePop 0.45s var(--v2-ease-emph);
}

@keyframes milestonePop {
  0%   { transform: translate(-50%, -50%) scale(0.85); opacity: 0; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}

.milestone-icon {
  font-family: var(--v2-font-display);
  font-size: 56px;
  font-weight: 700;
  background: linear-gradient(135deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  letter-spacing: -2px;
}

.milestone-title {
  font-family: var(--v2-font-display);
  font-size: 22px;
  font-weight: 700;
  margin-top: 8px;
}

.milestone-message {
  color: var(--v2-dim);
  font-size: 14px;
  margin-top: 8px;
}

.milestone-close {
  margin-top: 18px;
  background: linear-gradient(180deg, var(--v2-indigo) 0%, var(--v2-indigo-deep) 100%);
  color: #ffffff;
  border: none;
  padding: 10px 24px;
  font-family: var(--v2-font-display);
  font-weight: 700;
  cursor: pointer;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.20) inset,
    0 6px 18px -6px var(--v2-indigo-glow);
}

/* Hidden helpers for legacy IDs that tracker.js writes to but the v2 layout
   re-renders from elsewhere. Keep them present but invisible. */
.v2-legacy-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  pointer-events: none;
  opacity: 0;
}

/* ============================================================
   Reduced motion — respect user preference
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  body::after { display: none; }
  .v2-pace-bar .fill::after { display: none; }
  .charts-teaser-bg { animation: none; }
}

/* ============================================================
   POLISH LAYER v1 — hierarchy · depth · drama · mobile cockpit
   Purely additive: builds on existing tokens, never redefines layout.
   ============================================================ */

/* ---------- 1 · HEADLINE · richer numeric drama ---------- */

.v2-headline .accent-crimson {
  position: relative;
  display: inline-block;
  padding: 0 0.08em;
  background: linear-gradient(180deg, #ffb374 0%, var(--v2-orange) 60%, #c94913 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 10px 28px rgba(249, 115, 22, 0.35));
}
.v2-headline .accent-crimson::after {
  content: "";
  position: absolute;
  left: 6%; right: 6%;
  bottom: 0.08em;
  height: 4px;
  background: linear-gradient(90deg, transparent, var(--v2-orange) 50%, transparent);
  opacity: 0.55;
  filter: blur(2px);
  pointer-events: none;
}

/* Ahead-of-pace variant: reuse accent-crimson class but override for indigo-cyan */
.v2-headline.is-ahead .accent-crimson {
  background: linear-gradient(180deg, #b5f0ff 0%, var(--v2-cyan) 55%, #0ea5b7 100%);
  filter: drop-shadow(0 10px 28px rgba(34, 211, 238, 0.30));
}
.v2-headline.is-ahead .accent-crimson::after {
  background: linear-gradient(90deg, transparent, var(--v2-cyan) 50%, transparent);
}

/* The goal name gets a breathing underline + subtle glow pulse */
.v2-headline .accent-amber {
  position: relative;
}
.v2-headline .accent-amber::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: -4px;
  height: 2px;
  background: linear-gradient(90deg, transparent 0%, var(--v2-cyan) 30%, var(--v2-indigo) 70%, transparent 100%);
  transform: scaleX(0.2);
  transform-origin: center;
  opacity: 0.45;
  filter: blur(0.5px);
  animation: headlineAmberBreathe 4.2s ease-in-out infinite;
}
@keyframes headlineAmberBreathe {
  0%, 100% { transform: scaleX(0.25); opacity: 0.25; }
  50%      { transform: scaleX(1);    opacity: 0.75; }
}

/* ---------- 2 · KPI · layered depth + numeric presence ---------- */

.v2-kpi {
  isolation: isolate;
}
.v2-kpi::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 120% 60% at 50% 100%, rgba(129, 140, 248, 0.08), transparent 65%);
  opacity: 0;
  transition: opacity 0.3s var(--v2-ease-out);
  pointer-events: none;
  z-index: 0;
}
.v2-kpi:hover::after { opacity: 1; }
.v2-kpi > * { position: relative; z-index: 1; }

/* Widen the top accent bar on hover so the card feels "selected" */
.v2-kpi::before { transition: background 0.28s var(--v2-ease-out), height 0.28s var(--v2-ease-out); }
.v2-kpi:hover::before { height: 3px; }

/* The hero "Daily Needed" KPI: richer constant presence */
.v2-kpi:first-child {
  background:
    radial-gradient(ellipse 160% 70% at 0% 0%, rgba(129, 140, 248, 0.10), transparent 55%),
    var(--v2-card-bg);
}
.v2-kpi:first-child::before {
  height: 2px;
  background: linear-gradient(90deg, var(--v2-indigo) 0%, var(--v2-cyan) 60%, transparent 100%);
  box-shadow: 0 0 18px -4px var(--v2-indigo-glow);
}

/* Numeric values: embossed depth on hover */
.v2-kpi-value {
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.35);
  transition: transform 0.3s var(--v2-ease-emph), text-shadow 0.3s var(--v2-ease-out);
}
.v2-kpi:hover .v2-kpi-value {
  transform: translateY(-1px);
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.45), 0 0 24px rgba(129, 140, 248, 0.22);
}
.v2-kpi:hover .v2-kpi-value.amber {
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.45), 0 0 28px rgba(129, 140, 248, 0.45);
}

/* ---------- 3 · PACE BAR · calibration ticks + refined knob ---------- */

.v2-pace-bar {
  border-radius: 999px;
}
.v2-pace-bar .fill {
  border-radius: 999px;
}
.v2-pace-bar .knob {
  width: 18px; height: 18px;
  background:
    radial-gradient(circle at 30% 30%, #ffffff 0%, #e8ecff 45%, #c8cff0 100%);
  border: 2px solid #0a0c14;
}
.v2-pace-bar .knob::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, rgba(129, 140, 248, 0.55), transparent 70%);
  opacity: 0.6;
  animation: knobPulse 2.6s ease-in-out infinite;
}
@keyframes knobPulse {
  0%, 100% { opacity: 0.45; transform: scale(0.9); }
  50%      { opacity: 0.9;  transform: scale(1.1); }
}

/* Calibration ticks along the bar (every 25%) — subtle dashboard feel */
.v2-pace-bar::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0 calc(25% - 1px),
    rgba(255, 255, 255, 0.08) calc(25% - 1px) 25%
  );
  pointer-events: none;
  z-index: 1;
  border-radius: inherit;
}

/* ---------- 4 · RANK CARD · premium glyph pedestal ---------- */

.v2-rank-card {
  overflow: hidden;
}
.v2-rank-card::before {
  content: "";
  position: absolute;
  right: -20%; top: -30%;
  width: 260px; height: 260px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, rgba(34, 211, 238, 0.10), transparent 65%);
  pointer-events: none;
  z-index: 0;
}
.v2-rank-card > * { position: relative; z-index: 1; }

.v2-rank-glyph {
  width: 92px; height: 92px;
  background:
    radial-gradient(circle at 50% 35%, rgba(129, 140, 248, 0.25) 0%, rgba(129, 140, 248, 0.05) 40%, transparent 70%),
    radial-gradient(circle at 50% 80%, rgba(34, 211, 238, 0.12), transparent 55%);
}
.v2-rank-glyph::after {
  content: "";
  position: absolute;
  inset: auto 0 -14px 0;
  height: 10px;
  background: radial-gradient(ellipse 60% 100% at 50% 0%, rgba(129, 140, 248, 0.35), transparent 70%);
  filter: blur(3px);
  pointer-events: none;
}

.v2-rank-name {
  background: linear-gradient(180deg, #ffffff 0%, #d6dbee 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ---------- 5 · WEEK BAR · better empty state character ---------- */

.week-day-bar {
  border-radius: 3px;
}
.week-day.empty .week-day-bar {
  background:
    repeating-linear-gradient(
      135deg,
      rgba(129, 140, 248, 0.04) 0 6px,
      transparent 6px 12px
    ),
    linear-gradient(180deg, rgba(0, 0, 0, 0.28), rgba(129, 140, 248, 0.03));
}
.week-day.today .week-day-bar {
  outline: 1px solid rgba(129, 140, 248, 0.55);
  box-shadow:
    0 1px 1px rgba(0, 0, 0, 0.3) inset,
    0 0 0 3px rgba(129, 140, 248, 0.12);
}
.week-day.today .week-day-label {
  font-weight: 800;
  letter-spacing: 1.6px;
}

/* ---------- 6 · MATCH BUTTONS · sharper tactility ---------- */

.v2-match-btn {
  border-radius: 3px;
}
.v2-match-btn::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: linear-gradient(180deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  opacity: 0;
  transition: opacity 0.2s var(--v2-ease-out);
}
.v2-match-btn:hover::before { opacity: 0.8; }
.v2-match-btn.hero::before { display: none; } /* hero button owns its own gradient edge */

.v2-match-btn.hero {
  position: relative;
}
.v2-match-btn.hero::before {
  content: "";
  display: block;
  position: absolute;
  inset: 1px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.30), rgba(255,255,255,0) 45%);
  pointer-events: none;
  border-radius: inherit;
  opacity: 0.9;
}

/* ---------- 7 · MODE TABS · smoother indicator + highlight ---------- */

.v2-mode-tabs {
  border-radius: 999px;
  background:
    linear-gradient(180deg, rgba(0,0,0,0.25), rgba(129,140,248,0.03)),
    rgba(11, 16, 32, 0.65);
}
.v2-mode-tab {
  border-radius: 999px;
  transition: background 0.22s var(--v2-ease-out),
              color 0.18s var(--v2-ease-out),
              box-shadow 0.22s var(--v2-ease-out);
}
.v2-mode-tab.active {
  box-shadow:
    0 1px 0 rgba(255,255,255,0.30) inset,
    0 0 0 1px rgba(255,255,255,0.08),
    0 6px 14px -6px var(--v2-indigo-glow);
}

/* ---------- 8 · GOAL PILLS · sharpened hover + active depth ---------- */

.v2-goal-pill {
  border-radius: 4px;
}
.v2-goal-pill.active {
  border-radius: 4px;
  transform: translateY(-1px);
}
.v2-goal-pill.active::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 80% 60% at 50% 0%, rgba(255,255,255,0.25), transparent 70%);
  pointer-events: none;
  border-radius: inherit;
}

/* ---------- 9 · CHARTS TEASER · upgraded premium surface ---------- */

.charts-teaser {
  border-radius: 6px;
  position: relative;
}
.charts-teaser::after {
  content: "";
  position: absolute;
  left: 8%; right: 8%;
  bottom: 20%;
  height: 54px;
  background:
    linear-gradient(90deg, transparent 0%, rgba(34, 211, 238, 0.45) 50%, transparent 100%);
  mask-image:
    radial-gradient(ellipse 55% 50% at 15% 80%, #000 0%, transparent 70%),
    radial-gradient(ellipse 50% 60% at 45% 30%, #000 0%, transparent 70%),
    radial-gradient(ellipse 45% 40% at 75% 60%, #000 0%, transparent 70%),
    radial-gradient(ellipse 35% 45% at 92% 25%, #000 0%, transparent 70%);
  -webkit-mask-image:
    radial-gradient(ellipse 55% 50% at 15% 80%, #000 0%, transparent 70%),
    radial-gradient(ellipse 50% 60% at 45% 30%, #000 0%, transparent 70%),
    radial-gradient(ellipse 45% 40% at 75% 60%, #000 0%, transparent 70%),
    radial-gradient(ellipse 35% 45% at 92% 25%, #000 0%, transparent 70%);
  mask-composite: add;
  -webkit-mask-composite: source-over;
  filter: blur(1px);
  opacity: 0.6;
  pointer-events: none;
}
.charts-teaser h3 {
  font-size: clamp(24px, 2.4vw, 32px);
  letter-spacing: 0.04em;
}
.charts-teaser .discord-btn {
  padding: 11px 20px;
  font-size: 14px;
  letter-spacing: 0.4px;
  border-radius: 3px;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.18) inset,
    0 8px 22px -8px rgba(88, 101, 242, 0.55);
  transition: transform 0.15s var(--v2-ease-out), box-shadow 0.2s var(--v2-ease-out), background 0.15s;
}
.charts-teaser .discord-btn:hover {
  transform: translateY(-1px);
  box-shadow:
    0 1px 0 rgba(255,255,255,0.22) inset,
    0 12px 28px -8px rgba(88, 101, 242, 0.75);
}

/* ---------- 10 · LADDER · sharper pedestal for current tier ---------- */

.v2-ladder-cell {
  border-radius: 4px;
  overflow: hidden;
}
.v2-ladder-cell.current {
  transform: translateY(-3px);
}
.v2-ladder-cell.current::after {
  content: "";
  position: absolute;
  left: 10%; right: 10%;
  bottom: -10px;
  height: 8px;
  background: radial-gradient(ellipse 80% 100% at 50% 0%, rgba(129, 140, 248, 0.55), transparent 70%);
  filter: blur(2px);
  pointer-events: none;
}

/* ---------- 11 · CARDS · soft hover lift for pace + roadmap + week ---------- */

.v2-card,
.roadmap-card,
.pace-card,
.v2-mode-split,
.v2-ladder-card,
.v2-week,
.chart-card {
  border-radius: 4px;
  transition: box-shadow 0.28s var(--v2-ease-out), transform 0.28s var(--v2-ease-out);
}
.v2-card:hover,
.roadmap-card:hover,
.v2-mode-split:hover,
.v2-ladder-card:hover,
.v2-week:hover,
.chart-card:hover {
  box-shadow: var(--v2-card-shadow-hover);
}

/* ---------- 12 · TODAY BAR · subtle trophy treatment when done ---------- */

.v2-today {
  border-radius: 3px;
  position: relative;
  overflow: hidden;
}
.v2-today::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 60% 120% at 50% 100%, rgba(129, 140, 248, 0.06), transparent 70%);
  pointer-events: none;
}
.v2-today.done::before {
  background:
    radial-gradient(ellipse 60% 120% at 50% 100%, rgba(34, 197, 94, 0.18), transparent 70%);
}
.v2-today > * { position: relative; z-index: 1; }

/* ---------- 13 · ROADMAP · refined goal row + connective thread ---------- */

.roadmap-track {
  position: relative;
}
.roadmap-track::before {
  content: "";
  position: absolute;
  left: 18px; top: 18px; bottom: 18px;
  width: 1px;
  background: linear-gradient(180deg, transparent, rgba(129, 140, 248, 0.18) 15%, rgba(129, 140, 248, 0.18) 85%, transparent);
  pointer-events: none;
}
.roadmap-row {
  border-radius: 3px;
  position: relative;
}
.roadmap-row.goal {
  padding: 14px 14px;
}
.roadmap-row.goal .roadmap-name {
  background: linear-gradient(135deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
}
.roadmap-pip { box-shadow: 0 0 0 2px rgba(0,0,0,0.35), 0 0 6px currentColor; }

/* ---------- 14 · SIDEBAR · masthead refinement ---------- */

.v2-countdown-pill {
  border-radius: 3px;
  box-shadow:
    0 1px 0 rgba(255,255,255,0.45) inset,
    0 4px 12px -4px rgba(245, 166, 35, 0.55),
    0 0 0 1px rgba(245, 166, 35, 0.25);
}

/* ---------- 15 · SKELETON · classier shimmer ---------- */

.skeleton {
  background: linear-gradient(90deg,
    rgba(129, 140, 248, 0.04) 0%,
    rgba(129, 140, 248, 0.14) 50%,
    rgba(129, 140, 248, 0.04) 100%);
  border-radius: 3px;
}

/* ============================================================
   16 · MOBILE — sticky quick-log dock (THE mobile UX upgrade)
   A bottom action bar that keeps the primary win button reachable
   even when the user has scrolled into the live editorial view.
   Injected via pure CSS; uses the existing tracker.quickAddPoints API
   when we add the HTML hook (next edit). Purely progressive: if the
   .v2-quick-dock element isn't present, nothing renders.
   ============================================================ */

.v2-quick-dock {
  display: none; /* hidden by default — only shown on mobile via media query */
}

@media (max-width: 960px) {
  .v2-quick-dock {
    display: grid;
    position: fixed;
    left: 0; right: 0;
    bottom: 0;
    z-index: 50;
    grid-template-columns: 1fr 1fr 1fr auto;
    gap: 6px;
    padding: 8px 10px calc(8px + var(--v2-safe-bottom, 0px));
    background:
      linear-gradient(180deg, rgba(11, 16, 32, 0) 0%, rgba(11, 16, 32, 0.92) 30%, rgba(11, 16, 32, 0.98) 100%);
    backdrop-filter: blur(14px) saturate(1.2);
    -webkit-backdrop-filter: blur(14px) saturate(1.2);
    border-top: 1px solid rgba(129, 140, 248, 0.18);
    box-shadow: 0 -14px 40px -16px rgba(0, 0, 0, 0.7);
    pointer-events: auto;
    animation: dockRise 0.4s var(--v2-ease-emph) 0.2s both;
  }

  .v2-quick-dock .qd-btn {
    border: 1px solid var(--v2-border);
    background: linear-gradient(180deg, rgba(238, 242, 255, 0.035), transparent);
    color: var(--v2-ink);
    padding: 10px 6px;
    border-radius: 3px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    font-family: var(--v2-font-body);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.08s var(--v2-ease-out),
                border-color 0.18s var(--v2-ease-out),
                background 0.18s var(--v2-ease-out);
    min-height: 48px;
  }
  .v2-quick-dock .qd-btn:active { transform: scale(0.95); }
  .v2-quick-dock .qd-btn .pts {
    font-family: var(--v2-font-mono);
    font-size: 10px;
    letter-spacing: 1px;
    color: var(--v2-dim);
    font-weight: 700;
  }
  .v2-quick-dock .qd-btn .lbl {
    font-family: var(--v2-font-display);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.02em;
  }
  .v2-quick-dock .qd-btn.win {
    border: 1px solid transparent;
    background: linear-gradient(180deg, var(--v2-green-warm) 0%, var(--v2-green) 100%);
    color: #06210f;
    box-shadow:
      0 1px 0 rgba(255,255,255,0.35) inset,
      0 6px 16px -6px var(--v2-green-glow),
      0 0 0 1px rgba(34, 197, 94, 0.45);
  }
  .v2-quick-dock .qd-btn.win .pts { color: rgba(6, 33, 15, 0.75); }

  .v2-quick-dock .qd-undo {
    padding: 0 14px;
    background: rgba(129, 140, 248, 0.08);
    border: 1px solid rgba(129, 140, 248, 0.25);
    color: var(--v2-indigo);
    border-radius: 3px;
    font-family: var(--v2-font-mono);
    font-size: 12px;
    letter-spacing: 1.2px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 48px;
    font-weight: 700;
  }
  .v2-quick-dock .qd-undo:active { transform: scale(0.92); }

  /* Clearance so the dock never covers the last page content */
  .v2-main { padding-bottom: calc(120px + var(--v2-safe-bottom, 0px)); }

  /* Scotty FAB already small; nudge it up when dock is visible */
  #scotty-widget {
    bottom: calc(80px + var(--v2-safe-bottom, 0px)) !important;
  }
}

@keyframes dockRise {
  0%   { transform: translate3d(0, 100%, 0); opacity: 0; }
  100% { transform: translate3d(0, 0, 0);   opacity: 1; }
}

/* ---------- 17 · HEADLINE subtitle · richer wrap ---------- */

.v2-headline-sub strong {
  background: linear-gradient(180deg, transparent 60%, rgba(34, 211, 238, 0.18) 60%, rgba(129, 140, 248, 0.18) 100%);
  padding: 0 4px;
  border-radius: 2px;
}

/* ---------- 18 · EYEBROW · subtle live-indicator treatment ---------- */

.v2-eyebrow {
  padding: 4px 0;
}

/* ---------- 19 · SCROLLBAR · unobtrusive brand-aligned scrollbar ---------- */

* {
  scrollbar-width: thin;
  scrollbar-color: rgba(129, 140, 248, 0.35) transparent;
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, rgba(129, 140, 248, 0.35), rgba(34, 211, 238, 0.25));
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, rgba(129, 140, 248, 0.55), rgba(34, 211, 238, 0.4));
  background-clip: padding-box;
}

/* ---------- 20 · NOTIFICATION · radius consistency ---------- */
.notification { border-radius: 3px; }

/* ---------- 21 · POINTS INPUT WRAP · consistent radius ---------- */
.v2-points-input-wrap { border-radius: 3px; }

/* ---------- 22 · SIDEBAR SYNC · consistent radius ---------- */
.v2-sync { border-radius: 3px; }
.v2-sync-action { border-radius: 2px; }

/* ---------- 23 · REDUCED MOTION additions ---------- */
@media (prefers-reduced-motion: reduce) {
  .v2-headline .accent-amber::after,
  .v2-pace-bar .knob::after,
  .v2-quick-dock { animation: none !important; }
}

/* ============================================================
   POLISH LAYER v2 — compounding refinements
   Focus: tactile sheen, semantic trend glyphs, tier-colored pips,
   ghost empty states, micro-meters, premium FAB treatment.
   ============================================================ */

/* ---------- 24 · CARD SHEEN SWEEP on hover (the "premium" feel) ---------- */

.v2-card,
.v2-kpi,
.v2-today,
.roadmap-card,
.v2-week,
.v2-mode-split,
.v2-ladder-card,
.chart-card {
  position: relative;
}
.v2-card::before,
.v2-kpi.has-sheen::before,
.v2-today.has-sheen::before {
  /* reserved hook — existing ::before on kpi/today already has state */
}
/* Dedicated sheen layer via ::after where free, or a wrapping background sweep */
.v2-card,
.roadmap-card,
.v2-week,
.v2-mode-split,
.v2-ladder-card,
.chart-card {
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 40%, rgba(129, 140, 248, 0.025) 50%, rgba(255, 255, 255, 0) 60%, rgba(255, 255, 255, 0) 100%),
    var(--v2-card-bg);
  background-size: 220% 220%;
  background-position: 100% 0%;
  transition: box-shadow 0.28s var(--v2-ease-out),
              transform 0.28s var(--v2-ease-out),
              background-position 0.9s var(--v2-ease-emph);
}
.v2-card:hover,
.roadmap-card:hover,
.v2-week:hover,
.v2-mode-split:hover,
.v2-ladder-card:hover,
.chart-card:hover {
  background-position: 0% 100%;
}

/* ---------- 25 · KPI · trend glyphs on .stat-hint ---------- */

.v2-kpi .v2-kpi-sub {
  display: flex;
  align-items: center;
  gap: 6px;
}
.v2-kpi .v2-kpi-sub::before {
  content: "";
  width: 10px;
  height: 10px;
  flex-shrink: 0;
  background: currentColor;
  -webkit-mask: no-repeat center / contain;
          mask: no-repeat center / contain;
  opacity: 0;
  transform: translateY(0);
  transition: opacity 0.2s var(--v2-ease-out);
}
/* Positive trend — up triangle */
.v2-kpi .v2-kpi-sub.positive::before {
  opacity: 0.95;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><polygon points='5,1 9,8 1,8' fill='black'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><polygon points='5,1 9,8 1,8' fill='black'/></svg>");
}
/* Negative trend — down triangle */
.v2-kpi .v2-kpi-sub.negative::before {
  opacity: 0.95;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><polygon points='5,9 9,2 1,2' fill='black'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><polygon points='5,9 9,2 1,2' fill='black'/></svg>");
}
/* Accent hint — cyan dot */
.v2-kpi .v2-kpi-sub.accent {
  color: var(--v2-cyan);
}
.v2-kpi .v2-kpi-sub.accent::before {
  opacity: 0.9;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><circle cx='5' cy='5' r='3' fill='black'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'><circle cx='5' cy='5' r='3' fill='black'/></svg>");
}

/* ---------- 26 · ROADMAP PIPS · semantic tier color amplification ---------- */

.roadmap-pip {
  width: 16px; height: 16px;
  background:
    radial-gradient(circle at 50% 40%, currentColor 0%, rgba(0, 0, 0, 0.5) 45%, rgba(0, 0, 0, 0.65) 100%);
  box-shadow:
    0 0 0 2px rgba(0, 0, 0, 0.45),
    0 0 5px -1px currentColor,
    0 0 11px -4px currentColor;
}
.roadmap-row.goal .roadmap-pip {
  width: 18px; height: 18px;
  background:
    radial-gradient(circle at 50% 40%, #ffffff 0%, currentColor 40%, rgba(0, 0, 0, 0.5) 90%);
  box-shadow:
    0 0 0 2px rgba(0, 0, 0, 0.45),
    0 0 7px -1px currentColor,
    0 0 15px -4px currentColor;
}
.roadmap-row:hover .roadmap-pip {
  animation: pipPulse 1.8s ease-in-out infinite;
}
@keyframes pipPulse {
  0%, 100% { box-shadow: 0 0 0 2px rgba(0,0,0,0.45), 0 0 5px -1px currentColor, 0 0 11px -4px currentColor; }
  50%      { box-shadow: 0 0 0 2px rgba(0,0,0,0.45), 0 0 9px -1px currentColor, 0 0 18px -4px currentColor; }
}

/* The legacy connector line in tracker.css sits at left: 11px — far to the
   left of the pip center in the v3 grid layout. Re-anchor it on the pip
   center (~24px from row left) and self-center with translateX so it always
   threads through the middle of every circle, regardless of pip width. */
.roadmap-row:not(:last-child)::after {
  left: 24px;
  width: 1px;
  transform: translateX(-50%);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.10), rgba(255, 255, 255, 0.03));
}

/* ---------- 27 · TODAY BAR · bottom progress edge ---------- */

.v2-today {
  padding-bottom: 20px;
}
.v2-today::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  transform-origin: left;
  transform: scaleX(0.05);
  opacity: 0.5;
  transition: transform 0.6s var(--v2-ease-emph), opacity 0.3s var(--v2-ease-out), background 0.3s;
  z-index: 1;
}
.v2-today:not([data-empty="true"])::after {
  transform: scaleX(0.4);
  opacity: 0.7;
}
.v2-today.done::after {
  transform: scaleX(1);
  background: linear-gradient(90deg, var(--v2-green-warm) 0%, var(--v2-green) 100%);
  opacity: 1;
  box-shadow: 0 0 14px var(--v2-green-glow);
}

/* ---------- 28 · MODE SPLIT EMPTY · ghost bars for visual weight ---------- */

.v2-mode-empty {
  padding: 16px 18px 22px;
  position: relative;
  overflow: hidden;
}
.v2-mode-empty::after {
  content: "";
  display: block;
  margin-top: 14px;
  height: 6px;
  background:
    linear-gradient(90deg, rgba(129, 140, 248, 0.18) 0%, rgba(129, 140, 248, 0.04) 64%, transparent 64%) 0 0 / 100% 6px no-repeat,
    linear-gradient(90deg, rgba(129, 140, 248, 0.14) 0%, rgba(129, 140, 248, 0.02) 42%, transparent 42%) 0 10px / 100% 6px no-repeat,
    linear-gradient(90deg, rgba(129, 140, 248, 0.10) 0%, rgba(129, 140, 248, 0.02) 22%, transparent 22%) 0 20px / 100% 6px no-repeat;
  height: 26px;
  opacity: 0.85;
}

/* ---------- 29 · POINTS INPUT · value-change pulse via attr animation ---------- */

.v2-points-input-wrap {
  position: relative;
}
.v2-points-input-wrap::after {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: inherit;
  box-shadow: 0 0 0 2px rgba(129, 140, 248, 0);
  pointer-events: none;
  transition: box-shadow 0.5s var(--v2-ease-out);
}
.v2-points-input-wrap.flash::after {
  box-shadow: 0 0 0 2px rgba(129, 140, 248, 0.55), 0 0 24px rgba(129, 140, 248, 0.35);
  transition: box-shadow 0.1s var(--v2-ease-out);
}

/* ---------- 30 · SCOTTY FAB · brand-aligned orbit ring (desktop) ---------- */

@media (min-width: 641px) {
  #scotty-widget #scotty-toggle {
    position: relative;
    overflow: visible !important;
    box-shadow:
      0 10px 28px -8px rgba(245, 166, 35, 0.50),
      0 0 0 1px rgba(245, 166, 35, 0.35) !important;
  }
  #scotty-widget #scotty-toggle::after {
    content: "";
    position: absolute;
    inset: -6px;
    border-radius: 999px;
    border: 1px dashed rgba(245, 166, 35, 0.45);
    animation: scottyOrbitPulse 3.2s ease-in-out infinite;
    pointer-events: none;
  }
  @keyframes scottyOrbitPulse {
    0%, 100% { opacity: 0.55; transform: scale(1); }
    50%      { opacity: 0.95; transform: scale(1.03); }
  }
}

/* ---------- 31 · SYNC ROW · premium banner treatment ---------- */

.v2-sync {
  position: relative;
  background:
    linear-gradient(180deg, rgba(129, 140, 248, 0.05) 0%, rgba(11, 16, 32, 0.4) 100%);
  padding: 14px 14px;
}
.v2-sync.anon {
  background:
    linear-gradient(180deg, rgba(245, 166, 35, 0.05) 0%, rgba(11, 16, 32, 0.4) 100%);
  border: 1px solid rgba(245, 166, 35, 0.14);
}
.v2-sync.anon::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: linear-gradient(180deg, var(--v2-amber-warm), var(--v2-amber));
  opacity: 0.55;
}
.v2-sync .dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.v2-sync-action {
  font-weight: 800;
}
.v2-sync.anon .v2-sync-action {
  background: linear-gradient(180deg, var(--v2-amber-warm), var(--v2-amber));
  color: #1a1507;
  border-color: transparent;
  box-shadow: 0 1px 0 rgba(255,255,255,0.35) inset, 0 4px 12px -4px rgba(245, 166, 35, 0.55);
}
.v2-sync.anon .v2-sync-action:hover {
  background: linear-gradient(180deg, #fff4cf, var(--v2-amber-warm));
  color: #1a1507;
  filter: brightness(1.05);
}

/* ---------- 32 · LADDER · tier-colored top accent ---------- */

.v2-ladder-cell {
  padding-top: 20px;
}
.v2-ladder-cell::before {
  content: "";
  position: absolute;
  left: 10%; right: 10%;
  top: 0;
  height: 2px;
  background: currentColor;
  opacity: 0;
  transition: opacity 0.25s var(--v2-ease-out);
  pointer-events: none;
}
.v2-ladder-cell.passed::before { opacity: 0.35; }
.v2-ladder-cell.current::before {
  opacity: 0.95;
  background: linear-gradient(90deg, transparent, var(--v2-indigo) 50%, transparent);
  box-shadow: 0 0 12px var(--v2-indigo-glow);
}
/* Apply tier colors when available via rank-semantic data-attrs (cosmetic only) */
.v2-ladder-cell[data-tier="bronze"]   { color: #c87533; }
.v2-ladder-cell[data-tier="silver"]   { color: #c0c7d4; }
.v2-ladder-cell[data-tier="gold"]     { color: #f5c73a; }
.v2-ladder-cell[data-tier="platinum"] { color: #8dd8e8; }
.v2-ladder-cell[data-tier="diamond"]  { color: #b5baff; }
.v2-ladder-cell[data-tier="emerald"]  { color: #3ed39d; }

/* ---------- 33 · HEADLINE-SUB · refined "1,600" highlight ---------- */

.v2-headline-sub strong {
  position: relative;
  background: none;
  padding: 0 3px;
  color: var(--v2-ink);
  font-weight: 700;
}
.v2-headline-sub strong::before {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 8px;
  background: linear-gradient(90deg, var(--v2-cyan), var(--v2-indigo));
  opacity: 0.22;
  border-radius: 2px;
  z-index: -1;
  filter: blur(0.5px);
}

/* ---------- 34 · SEGMENTED CONTROL INDICATOR · smoother transition ---------- */

.v2-mode-tabs {
  overflow: hidden;
}
.v2-mode-tab {
  transition: color 0.15s var(--v2-ease-out),
              background 0.3s var(--v2-ease-emph),
              box-shadow 0.3s var(--v2-ease-emph),
              transform 0.15s var(--v2-ease-out);
}
.v2-mode-tab:not(.active):hover {
  color: var(--v2-ink);
  background: rgba(129, 140, 248, 0.06);
}

/* ---------- 35 · GOAL-PILL · subtle highlight chip on active ---------- */

.v2-goal-pill.active {
  position: relative;
}
.v2-goal-pill.active::before {
  /* the left-rail indicator already exists; add a chip in the corner */
  content: "";
  position: absolute;
  top: 6px; right: 6px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 0 8px rgba(255, 255, 255, 0.75);
  opacity: 0.95;
  z-index: 2;
}

/* ---------- 36 · QUICK-DOCK (mobile) · subtle mode chip ---------- */

@media (max-width: 960px) {
  .v2-quick-dock::before {
    content: "QUICK LOG";
    position: absolute;
    left: 50%;
    top: -18px;
    transform: translateX(-50%);
    padding: 3px 10px 3px 10px;
    background: rgba(11, 16, 32, 0.92);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border: 1px solid rgba(129, 140, 248, 0.22);
    border-bottom: none;
    color: var(--v2-indigo);
    font-family: var(--v2-font-mono);
    font-size: 9px;
    letter-spacing: 2px;
    font-weight: 800;
    border-radius: 999px 999px 0 0;
    pointer-events: none;
  }
}

/* ---------- 37 · NUMBER SHIMMER on first reveal ---------- */

.v2-kpi-value:not(.skeleton) {
  animation: valueReveal 0.6s var(--v2-ease-emph) both;
}
@keyframes valueReveal {
  0%   { opacity: 0; transform: translateY(4px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* ---------- 38 · CURRENT-RANK-NAME · breathing sheen on the gradient text ---------- */

.v2-rank-name {
  background-size: 200% 100%;
  background-position: 0 0;
  animation: rankNameSheen 6s ease-in-out infinite;
}
@keyframes rankNameSheen {
  0%, 100% { background-position: 0 0; }
  50%      { background-position: 100% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .v2-rank-name { animation: none; }
}

/* ---------- 39 · FIRST-TIME OVERLAY · richer entrance ---------- */

.first-time-content {
  border-radius: 6px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    0 0 0 1px rgba(129, 140, 248, 0.25),
    0 30px 80px -20px rgba(0, 0, 0, 0.8),
    0 0 60px -20px var(--v2-indigo-glow);
  animation: ftEnter 0.5s var(--v2-ease-emph) both;
}
@keyframes ftEnter {
  0%   { opacity: 0; transform: translateY(8px) scale(0.98); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* ---------- 40 · REDUCED MOTION additions for v2 ---------- */

@media (prefers-reduced-motion: reduce) {
  .roadmap-row:hover .roadmap-pip,
  #scotty-widget #scotty-toggle::after,
  .v2-rank-name,
  .v2-kpi-value:not(.skeleton) { animation: none !important; }
  .v2-card,
  .roadmap-card,
  .v2-week,
  .v2-mode-split,
  .v2-ladder-card,
  .chart-card { background-position: 100% 0%; }
}

/* ============================================================
   POLISH LAYER v3 — ambient depth · cinematic detail
   Focus: aurora backdrop, tier left-rails, live sparkline teaser,
   pace-bar tier checkpoints, mobile masthead tightening.
   ============================================================ */

/* ---------- 41 · AURORA · slow atmospheric gradient behind main ---------- */

.v2-main {
  isolation: isolate;
}
.v2-main::after {
  content: "";
  position: absolute;
  inset: -10% -5% 30% -5%;
  z-index: -1;
  background:
    radial-gradient(ellipse 60% 40% at 20% 15%, rgba(34, 211, 238, 0.06), transparent 60%),
    radial-gradient(ellipse 40% 30% at 80% 25%, rgba(129, 140, 248, 0.08), transparent 65%),
    radial-gradient(ellipse 50% 40% at 60% 70%, rgba(34, 197, 94, 0.03), transparent 65%);
  pointer-events: none;
  filter: blur(14px);
  animation: auroraDrift 22s ease-in-out infinite alternate;
}
@keyframes auroraDrift {
  0%   { transform: translate3d(0, 0, 0) scale(1); opacity: 0.85; }
  50%  { transform: translate3d(2%, -1%, 0) scale(1.04); opacity: 1; }
  100% { transform: translate3d(-1%, 2%, 0) scale(0.98); opacity: 0.9; }
}
@media (prefers-reduced-motion: reduce) {
  .v2-main::after { animation: none; }
}

/* ---------- 42 · ROADMAP · tier-colored left rails via row currentColor ---------- */

.roadmap-row {
  border-left: 2px solid transparent;
  transition: border-color 0.22s var(--v2-ease-out),
              background 0.22s var(--v2-ease-out);
}
.roadmap-row:not(.goal) {
  border-left-color: color-mix(in srgb, currentColor 35%, transparent);
}
.roadmap-row:hover:not(.goal) {
  border-left-color: currentColor;
  background: linear-gradient(90deg, color-mix(in srgb, currentColor 10%, transparent) 0%, transparent 60%);
}
.roadmap-row.goal {
  border-left-color: currentColor;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    inset 4px 0 0 -2px color-mix(in srgb, currentColor 60%, transparent),
    0 0 18px -6px var(--v2-indigo-glow);
}

/* ---------- 43 · CHARTS TEASER · live sparkline fake preview ---------- */

.charts-teaser::before {
  /* existing grid still renders — augment with a fake chart line */
}
.charts-teaser-bg::after {
  content: "";
  position: absolute;
  left: 8%; right: 8%;
  bottom: 22%;
  height: 90px;
  background:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 100' preserveAspectRatio='none'><defs><linearGradient id='g' x1='0' x2='0' y1='0' y2='1'><stop offset='0%' stop-color='%2322d3ee' stop-opacity='0.5'/><stop offset='100%' stop-color='%23818cf8' stop-opacity='0'/></linearGradient><linearGradient id='s' x1='0' x2='1'><stop offset='0%' stop-color='%23818cf8'/><stop offset='100%' stop-color='%2322d3ee'/></linearGradient></defs><path d='M0 80 L40 70 L80 72 L120 55 L160 58 L200 40 L240 45 L280 30 L320 25 L360 18 L400 12' stroke='url(%23s)' stroke-width='2.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/><path d='M0 80 L40 70 L80 72 L120 55 L160 58 L200 40 L240 45 L280 30 L320 25 L360 18 L400 12 L400 100 L0 100 Z' fill='url(%23g)'/></svg>") center/100% 100% no-repeat;
  opacity: 0.55;
  pointer-events: none;
  filter: drop-shadow(0 4px 12px rgba(34, 211, 238, 0.2));
}
.charts-teaser::after {
  /* hide the old blob version — let the sparkline speak */
  display: none;
}

/* ---------- 44 · PACE BAR · tier checkpoint ticks ---------- */

.v2-rank-progress-card .v2-pace-bar {
  margin-bottom: 6px;
}
.v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  margin-top: 6px;
  font-family: var(--v2-font-mono);
  font-size: 8.5px;
  letter-spacing: 1.2px;
  color: var(--v2-faint);
  text-transform: uppercase;
  font-weight: 700;
}
.v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks span {
  text-align: left;
  opacity: 0.55;
}
.v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks span.reached { opacity: 1; color: var(--v2-indigo); }

/* ---------- 45 · RANK GLYPH · chromatic rim + inner light ---------- */

.v2-rank-glyph {
  position: relative;
}
.v2-rank-glyph > * {
  position: relative;
  z-index: 2;
  filter: drop-shadow(0 3px 8px rgba(34, 211, 238, 0.35)) drop-shadow(0 0 4px rgba(129, 140, 248, 0.3));
}
.v2-rank-glyph::before {
  /* already used for conic halo — preserve */
}

/* ---------- 46 · TODAY · inviting "0" state with shimmer hint ---------- */

.v2-today .value.green.zero {
  position: relative;
}
.v2-today .value.green.zero::after {
  content: "";
  position: absolute;
  left: -2px; right: -2px;
  bottom: -4px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(129, 140, 248, 0.4), transparent);
  opacity: 0;
  animation: todayHint 4.5s ease-in-out infinite;
}
@keyframes todayHint {
  0%, 100% { opacity: 0; transform: scaleX(0.3); }
  50%      { opacity: 0.8; transform: scaleX(1); }
}
.v2-today .label {
  position: relative;
}

/* ---------- 47 · MOBILE MASTHEAD · one-line compact at ≤480 ---------- */

@media (max-width: 480px) {
  .v2-masthead {
    align-items: center;
    padding-bottom: 10px;
  }
  .v2-masthead > div:first-child {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
  }
  .v2-masthead-title {
    font-size: 22px;
    display: inline-block;
  }
  .v2-masthead-sub {
    margin-top: 0;
    font-size: 10px;
    letter-spacing: 1.5px;
  }
  .v2-countdown-pill {
    font-size: 9.5px;
    padding: 4px 8px;
    letter-spacing: 1.2px;
  }
}

/* ---------- 48 · FOOTER · branded divider hairline ---------- */

.page-footer {
  position: relative;
}
.page-footer::before {
  content: "";
  position: absolute;
  left: 50%; top: 0;
  transform: translateX(-50%);
  width: min(100%, 600px);
  height: 1px;
  background: linear-gradient(90deg, transparent 0%, var(--v2-amber) 40%, var(--v2-indigo) 60%, transparent 100%);
  opacity: 0.5;
}

/* ---------- 49 · LADDER GLYPHS · tier-tinted shine when passed ---------- */

.v2-ladder-cell.passed .v2-ladder-glyph {
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.5)) drop-shadow(0 0 8px color-mix(in srgb, currentColor 35%, transparent));
}
.v2-ladder-cell.current .v2-ladder-glyph {
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.6)) drop-shadow(0 0 14px color-mix(in srgb, currentColor 55%, transparent));
}

/* ---------- 50 · POINTS INPUT (mobile) · larger steppers ---------- */

@media (max-width: 640px) {
  .v2-points-step {
    min-width: 56px;
    min-height: 64px;
    font-size: 28px;
  }
  .v2-points-input {
    height: 64px;
    font-size: 40px;
  }
}

/* ---------- 51 · "LIVE" BROADCAST DOTS · one tweak: section-label glow ---------- */

.v2-section-label > span:first-child::before {
  background: linear-gradient(90deg, var(--v2-indigo), var(--v2-cyan));
  box-shadow: 0 0 10px rgba(129, 140, 248, 0.7);
}

/* ---------- 52 · NOTIFICATION TOAST · brand polish ---------- */

.notification {
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  background: linear-gradient(180deg, rgba(26, 31, 48, 0.85), rgba(20, 24, 38, 0.85));
}

/* ---------- 53 · LAST-UPDATED · micro-pill chip instead of raw text
     Moved to bottom-right so it never collides with the sticky cockpit's
     WIN button at bottom-left. On mobile (cockpit stacks at top), leave
     it where it was. ---------- */

.last-updated {
  left: auto;
  right: 12px;
  bottom: 14px;
  padding: 4px 10px;
  background: rgba(11, 16, 32, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border: 1px solid var(--v2-border-soft);
  border-radius: 999px;
  pointer-events: auto;
  font-size: 9.5px;
  letter-spacing: 1.4px;
  color: var(--v2-dim);
  text-transform: uppercase;
  font-weight: 600;
}
@media (max-width: 960px) {
  /* Hide on mobile — the quick-log dock owns the bottom band */
  .last-updated { display: none; }
}
/* Desktop: nudge further left so it doesn't crowd the Scotty FAB */
@media (min-width: 961px) {
  .last-updated { right: 140px; }
}

/* ---------- 54 · Z-INDEX SAFETY · keep dock + scotty above new aurora ---------- */

.v2-quick-dock { z-index: 60; }
#scotty-widget { z-index: 55; }
.last-updated  { z-index: 56; }

/* ---------- 55 · FOCUS-VISIBLE polish ---------- */

:focus-visible {
  box-shadow:
    0 0 0 2px var(--v2-bg),
    0 0 0 4px rgba(129, 140, 248, 0.55),
    0 0 18px -4px var(--v2-indigo-glow);
  border-radius: 3px;
}

/* ---------- 56 · PACE BAR knob label (shows points on hover) ---------- */

.v2-pace-bar:hover .knob::before {
  content: attr(data-pts);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 10px);
  transform: translateX(-50%);
  background: rgba(11, 16, 32, 0.92);
  color: var(--v2-ink);
  font-family: var(--v2-font-mono);
  font-size: 10px;
  letter-spacing: 1px;
  padding: 4px 8px;
  border-radius: 3px;
  border: 1px solid rgba(129, 140, 248, 0.35);
  white-space: nowrap;
  box-shadow: 0 6px 18px -6px rgba(0,0,0,0.6);
  opacity: 1;
}

/* ---------- 57 · PAGE-LEVEL fade-in so first paint doesn't snap ---------- */

.v2-shell {
  animation: shellFadeIn 0.5s var(--v2-ease-out) both;
}
@keyframes shellFadeIn {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}

/* ---------- 58 · POINTS HINT · first-run callout pointing at input ---------- */

.v2-points-hint {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 10px;
  padding: 10px 12px;
  border-radius: 3px;
  background: var(--v2-indigo-soft);
  border: 1px solid rgba(129, 140, 248, 0.35);
  color: var(--v2-indigo);
  font-size: 12.5px;
  letter-spacing: 0.2px;
  line-height: 1.35;
  box-shadow: 0 0 0 0 rgba(129, 140, 248, 0);
  animation: pointsHintPulse 2.8s var(--v2-ease-out) infinite;
  transform-origin: 50% 100%;
}

.v2-points-hint[hidden] {
  display: none;
}

.v2-points-hint-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  border-radius: 50%;
  background: linear-gradient(180deg, var(--v2-indigo) 0%, var(--v2-indigo-deep) 100%);
  color: #0a0c14;
  font-weight: 800;
  font-size: 13px;
  line-height: 1;
  box-shadow: 0 4px 10px -4px var(--v2-indigo-glow);
  animation: pointsHintArrow 1.6s var(--v2-ease-out) infinite;
}

.v2-points-hint-text {
  flex: 1 1 auto;
  min-width: 0;
}

@keyframes pointsHintPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(129, 140, 248, 0); }
  50%      { box-shadow: 0 0 0 4px rgba(129, 140, 248, 0.12); }
}

@keyframes pointsHintArrow {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(3px); }
}

@media (prefers-reduced-motion: reduce) {
  .v2-points-hint,
  .v2-points-hint-arrow {
    animation: none;
  }
}

/* ============================================================
   POLISH LAYER v4 — elevate the new activation hint + compound polish
   ============================================================ */

/* ---------- 58b · V2-POINTS-HINT · broadcast-grade elevation ----------
   Builds on the user's baseline hint. Adds: depth gradient, radial corner
   wash, connecting tail pointing at the input, paired breathing glow on
   the input below so the two elements read as a single activation surface. */

.v2-points-hint {
  position: relative;
  padding: 11px 14px 11px 12px;
  background:
    linear-gradient(135deg, rgba(129, 140, 248, 0.18), rgba(34, 211, 238, 0.10));
  color: var(--v2-ink);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 0 0 1px rgba(129, 140, 248, 0.14),
    0 14px 30px -16px var(--v2-indigo-glow);
  overflow: visible;
  z-index: 2;
}

/* Corner radial wash — adds depth the flat soft-color base can't */
.v2-points-hint::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 75% 90% at 0% 0%, rgba(129, 140, 248, 0.22), transparent 60%);
  border-radius: inherit;
  pointer-events: none;
}

/* Little tail that visually points the callout down at the input below */
.v2-points-hint::after {
  content: "";
  position: absolute;
  left: 22px;
  bottom: -6px;
  width: 12px;
  height: 12px;
  background: linear-gradient(135deg, rgba(129, 140, 248, 0.35), rgba(34, 211, 238, 0.18));
  border-right: 1px solid rgba(129, 140, 248, 0.35);
  border-bottom: 1px solid rgba(129, 140, 248, 0.35);
  transform: rotate(45deg);
  z-index: -1;
}

.v2-points-hint-arrow {
  width: 26px;
  height: 26px;
  font-size: 14px;
  color: #ffffff;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.35) inset,
    0 4px 12px -4px var(--v2-indigo-glow),
    0 0 0 3px rgba(129, 140, 248, 0.18);
}

.v2-points-hint-text {
  color: var(--v2-ink);
  font-weight: 500;
  font-size: 13px;
}
.v2-points-hint-text strong {
  color: var(--v2-cyan);
  font-weight: 700;
}

/* Pair hint + input visually — input below breathes softly as long as the
   hint is visible, so the user's eye travels naturally from the callout to
   the thing to interact with. Kills the breathing on focus (user's here). */
.v2-points-hint:not([hidden]) + .v2-points-input-wrap {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 0 0 1px var(--v2-indigo),
    0 0 0 3px rgba(129, 140, 248, 0.18),
    0 6px 18px -10px rgba(0, 0, 0, 0.6);
  animation: hintInputBreathe 2.8s ease-in-out infinite;
}
@keyframes hintInputBreathe {
  0%, 100% {
    box-shadow:
      0 1px 0 rgba(255, 255, 255, 0.06) inset,
      0 0 0 1px var(--v2-indigo),
      0 0 0 3px rgba(129, 140, 248, 0.18),
      0 6px 18px -10px rgba(0, 0, 0, 0.6);
  }
  50% {
    box-shadow:
      0 1px 0 rgba(255, 255, 255, 0.08) inset,
      0 0 0 1px var(--v2-indigo),
      0 0 0 5px rgba(129, 140, 248, 0.28),
      0 10px 24px -10px rgba(0, 0, 0, 0.6);
  }
}
.v2-points-hint:not([hidden]) + .v2-points-input-wrap:focus-within {
  animation: none;
}
@media (prefers-reduced-motion: reduce) {
  .v2-points-hint:not([hidden]) + .v2-points-input-wrap { animation: none !important; }
}

@media (max-width: 480px) {
  .v2-points-hint { padding: 10px 12px; gap: 9px; }
  .v2-points-hint-arrow { width: 24px; height: 24px; font-size: 13px; }
  .v2-points-hint-text { font-size: 12.5px; }
  .v2-points-hint::after { left: 20px; width: 10px; height: 10px; bottom: -5px; }
}

/* ---------- 59 · GOAL PILL · tier color on hover ---------- */

.v2-goal-pill[data-tier="bronze"]   { --tier: #c87533; }
.v2-goal-pill[data-tier="silver"]   { --tier: #c0c7d4; }
.v2-goal-pill[data-tier="gold"]     { --tier: #f5c73a; }
.v2-goal-pill[data-tier="platinum"] { --tier: #8dd8e8; }
.v2-goal-pill[data-tier="diamond"]  { --tier: #b5baff; }
.v2-goal-pill[data-tier="emerald"]  { --tier: #3ed39d; }
.v2-goal-pill[data-tier]:hover:not(.active) {
  border-color: color-mix(in srgb, var(--tier, var(--v2-indigo)) 45%, transparent);
  background: color-mix(in srgb, var(--tier, var(--v2-indigo)) 8%, transparent);
}
.v2-goal-pill[data-tier]:hover:not(.active)::before {
  background: var(--tier, var(--v2-indigo));
  opacity: 0.75;
}

/* ---------- 60 · COUNTDOWN PILL · scanning broadcast shine ---------- */

.v2-countdown-pill {
  position: relative;
  overflow: hidden;
}
.v2-countdown-pill::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.40) 50%, transparent 70%);
  transform: translateX(-110%);
  animation: countdownShine 5s ease-in-out infinite;
  pointer-events: none;
}
@keyframes countdownShine {
  0%, 55%  { transform: translateX(-110%); }
  72%      { transform: translateX(210%); }
  100%     { transform: translateX(210%); }
}
@media (prefers-reduced-motion: reduce) {
  .v2-countdown-pill::after { animation: none; }
}

/* ---------- 61 · KPI · stagger entrance (compound with Pass 1 reveal) ---------- */

.v2-kpi { animation-fill-mode: both; }
.v2-kpi:nth-child(1) { animation-delay: 0.00s; }
.v2-kpi:nth-child(2) { animation-delay: 0.06s; }
.v2-kpi:nth-child(3) { animation-delay: 0.12s; }
.v2-kpi:nth-child(4) { animation-delay: 0.18s; }
.v2-kpi {
  animation: kpiRise 0.55s var(--v2-ease-emph) both;
}
@keyframes kpiRise {
  0%   { opacity: 0; transform: translateY(6px); }
  100% { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .v2-kpi { animation: none !important; }
}

/* ---------- 62 · ROADMAP · subtle kinetic nudge on hover ---------- */

.roadmap-row:not(.goal) {
  transition:
    border-color 0.22s var(--v2-ease-out),
    background 0.22s var(--v2-ease-out),
    transform 0.18s var(--v2-ease-out);
}
.roadmap-row:not(.goal):hover {
  transform: translateX(2px);
}

/* ---------- 63 · WEEK-DAY · hover highlights the day column ---------- */

.week-day:hover .week-day-bar {
  outline: 1px solid rgba(129, 140, 248, 0.45);
}

/* ---------- 64 · SIDEBAR · soft top fade to align with navbar shadow ---------- */

.v2-sidebar::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 36px;
  background: linear-gradient(180deg, rgba(10, 12, 20, 0.85), transparent);
  pointer-events: none;
  z-index: 0;
}
.v2-sidebar > * { position: relative; z-index: 1; }

/* ---------- 65 · INPUT SELECTION · brand-aligned selection color ---------- */

.v2-points-input::selection {
  background: rgba(129, 140, 248, 0.35);
  color: var(--v2-ink);
}

/* ---------- 66 · FIRST-TIME BUTTON · press feedback ---------- */

.first-time-button { border-radius: 3px; }
.first-time-button:active { transform: scale(0.98); }

/* ============================================================
   POLISH LAYER v5 — editorial discipline · world-class detail
   Focus: headline finesse, pace-bar tactility, week-bar baselines,
   CSS-drawn pace glyph (replaces emoji), ladder magnet, mode-split
   gradient rhythm, mobile density tightening, scroll snap rhythm.
   ============================================================ */

/* ---------- 67 · HEADLINE · editorial tracking + underline motion ---------- */

.v2-headline {
  /* Tighten display kerning at hero sizes; 0.01em feels cramped at 78px on desktop */
  letter-spacing: -0.005em;
  line-height: 0.96;
  text-wrap: balance;
}

/* Restrained amber-path underline: softer, with a breathing-width animation */
.v2-headline .accent-amber {
  text-decoration: none; /* replaced with ::after for animation control */
  position: relative;
  padding-bottom: 6px;
}
.v2-headline .accent-amber::before {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: 0;
  height: 3px;
  background: linear-gradient(90deg,
    rgba(129, 140, 248, 0.9) 0%,
    rgba(34, 211, 238, 0.9) 50%,
    rgba(129, 140, 248, 0.9) 100%);
  background-size: 200% 100%;
  animation: headlineUnderlineFlow 7s ease-in-out infinite;
  border-radius: 2px;
  filter: drop-shadow(0 2px 10px rgba(129, 140, 248, 0.35));
}
@keyframes headlineUnderlineFlow {
  0%, 100% { background-position: 0% 0%; }
  50%      { background-position: 100% 0%; }
}
@media (prefers-reduced-motion: reduce) {
  .v2-headline .accent-amber::before { animation: none; }
}

/* Trailing dot — bring it snug against the gradient text, keep ink color */
.v2-headline .dot {
  position: relative;
  top: -0.04em;
  margin-left: -0.02em;
  opacity: 0.75;
}

/* "PTS/DAY" — dim the cyan so the goal rank stays the dominant accent */
.v2-headline .accent-pace {
  color: var(--v2-cyan);
  filter: drop-shadow(0 0 14px rgba(34, 211, 238, 0.22));
  font-weight: 700;
}

/* ---------- 68 · HEADLINE SUB · chip-like pace badge with icon ---------- */

.v2-headline-sub {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  line-height: 1.55;
}

.v2-pace-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 8px;
}
.v2-pace-chip::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 25%, transparent),
              0 0 8px currentColor;
  flex-shrink: 0;
}

/* ---------- 69 · PACE BAR · more tactile knob + refined "ON PACE" flag ---------- */

.v2-pace-bar {
  height: 12px;   /* 14 → 12 reads more precision-instrument */
  border-radius: 2px;
  overflow: visible;
}
.v2-pace-bar::before {
  /* Baseline grid — faint dashes behind the fill for data-viz cues */
  content: "";
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(90deg,
      rgba(255,255,255,0.025) 0 1px,
      transparent 1px calc(100% / 24));
  pointer-events: none;
  z-index: 0;
  opacity: 0.7;
}
.v2-pace-bar .fill {
  border-radius: 1.5px;
  z-index: 1;
}

/* "ON PACE" label becomes a tiny notched flag */
.v2-pace-bar .pace-marker-label {
  top: -28px;
  padding: 3px 8px 3px 8px;
  background: rgba(11, 16, 32, 0.92);
  border: 1px solid rgba(129, 140, 248, 0.30);
  color: var(--v2-indigo);
  letter-spacing: 1.6px;
  font-size: 9.5px;
  box-shadow: 0 4px 10px -4px rgba(0,0,0,0.5);
  border-radius: 2px;
}
.v2-pace-bar .pace-marker-label::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -4px;
  width: 0; height: 0;
  transform: translateX(-50%);
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid rgba(129, 140, 248, 0.30);
}

/* Knob: more 3D, chromatic rim + inner highlight; scales subtly on hover */
.v2-pace-bar .knob {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 35% 30%, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0.35) 22%, transparent 30%),
    linear-gradient(180deg, #ffffff 0%, var(--v2-indigo) 60%, var(--v2-indigo-deep) 100%);
  box-shadow:
    0 0 0 2px var(--v2-bg),
    0 0 0 3px rgba(129, 140, 248, 0.45),
    0 6px 14px -2px rgba(0, 0, 0, 0.6),
    0 0 18px rgba(129, 140, 248, 0.35);
  transition: transform 0.2s var(--v2-ease-emph), box-shadow 0.25s var(--v2-ease-out);
  cursor: grab;
}
.v2-pace-bar:hover .knob {
  transform: translateY(-1px) scale(1.06);
  box-shadow:
    0 0 0 2px var(--v2-bg),
    0 0 0 3px rgba(129, 140, 248, 0.60),
    0 10px 22px -4px rgba(0, 0, 0, 0.65),
    0 0 26px rgba(129, 140, 248, 0.55);
}

/* Behind-pace knob: warm orange skin */
.v2-pace-bar.behind .knob {
  background:
    radial-gradient(circle at 35% 30%, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0.30) 22%, transparent 30%),
    linear-gradient(180deg, #ffd7b8 0%, var(--v2-orange) 60%, #c55008 100%);
  box-shadow:
    0 0 0 2px var(--v2-bg),
    0 0 0 3px rgba(249, 115, 22, 0.45),
    0 6px 14px -2px rgba(0, 0, 0, 0.6),
    0 0 18px rgba(249, 115, 22, 0.45);
}

/* Goal-met knob: green */
.v2-pace-bar.met .knob,
.v2-pace-bar.ahead .knob {
  background:
    radial-gradient(circle at 35% 30%, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0.30) 22%, transparent 30%),
    linear-gradient(180deg, #cff9d9 0%, var(--v2-green) 60%, #16803c 100%);
  box-shadow:
    0 0 0 2px var(--v2-bg),
    0 0 0 3px rgba(34, 197, 94, 0.50),
    0 6px 14px -2px rgba(0, 0, 0, 0.6),
    0 0 20px rgba(34, 197, 94, 0.50);
}

/* ---------- 70 · PACE META · clean alignment + iconography ---------- */

.v2-pace-meta {
  font-size: 10.5px;
  letter-spacing: 1.8px;
}
.v2-pace-meta .current {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  color: var(--v2-ink);
  font-size: 12px;
  letter-spacing: 1px;
}
.v2-pace-meta .current::before {
  content: "◆";
  color: var(--v2-indigo);
  font-size: 9px;
  margin-right: 4px;
  filter: drop-shadow(0 0 6px var(--v2-indigo-glow));
}

/* ---------- 71 · TODAY BAR · balanced hierarchy + inline mini-meter ---------- */

.v2-today {
  padding: 16px 24px 22px;
  gap: 24px;
}
.v2-today .group {
  gap: 14px;
}
.v2-today .group.right {
  flex-direction: row-reverse;
  gap: 14px;
}
.v2-today .group.right .label {
  text-align: left;
}
.v2-today .label {
  font-size: 10.5px;
  letter-spacing: 2.2px;
  opacity: 0.95;
}
.v2-today .value {
  font-size: 30px;
}

/* ---------- 72 · WEEK BAR · crisper baseline + top goal-line + quiet empty-day ---------- */

.week-day-bar {
  /* Add top + bottom hairline so every day has visual anchor, even empty */
  background:
    linear-gradient(0deg, rgba(255,255,255,0.08) 0 1px, transparent 1px calc(100% - 1px), rgba(255,255,255,0.05) calc(100% - 1px) 100%),
    linear-gradient(180deg, rgba(0, 0, 0, 0.28), rgba(238, 242, 255, 0.04));
  transition: outline 0.18s var(--v2-ease-out), transform 0.18s var(--v2-ease-out);
}
.week-day-bar::before {
  /* Goal-line: a subtle dashed tick across all days, not just one */
  background: repeating-linear-gradient(90deg,
    rgba(129, 140, 248, 0.42) 0 5px,
    transparent 5px 9px);
  box-shadow: none;
  opacity: 0.85;
}
.week-day.empty .week-day-bar {
  background:
    linear-gradient(0deg, rgba(255,255,255,0.08) 0 1px, transparent 1px calc(100% - 1px), rgba(255,255,255,0.05) calc(100% - 1px) 100%),
    repeating-linear-gradient(135deg, rgba(255, 255, 255, 0.02) 0 6px, transparent 6px 12px),
    linear-gradient(180deg, rgba(0, 0, 0, 0.25), rgba(238, 242, 255, 0.03));
}
.week-day:hover .week-day-bar {
  outline: 1px solid rgba(129, 140, 248, 0.55);
  transform: translateY(-1px);
}
.week-day-fill {
  /* subtle inner highlight on the fill so it reads dimensional, not flat */
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.18) inset,
    0 0 10px var(--v2-indigo-glow);
}
.week-day-fill.met {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.22) inset,
    0 0 12px var(--v2-green-glow);
}
.week-day-pts {
  font-size: 11.5px;
  opacity: 0.95;
}
.week-day.today .week-day-pts {
  color: var(--v2-indigo);
  font-weight: 800;
  text-shadow: 0 0 8px rgba(129, 140, 248, 0.55);
}

/* ---------- 73 · PACE ICON · CSS glyph replaces 🔴 / 🟢 emoji ----------
   Keeps JS untouched — emoji text gets masked and a drawn glyph overlays. */

.pace-icon {
  width: 34px;
  height: 34px;
  font-size: 0;       /* hides the emoji text */
  color: transparent; /* hides text color */
  position: relative;
  grid-row: 1 / span 2;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.pace-icon::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: transparent;
  -webkit-mask: center/18px 18px no-repeat;
          mask: center/18px 18px no-repeat;
}
/* Status color propagates via sibling .pace-text — we match on siblings */
.pace-status .pace-icon::after {
  /* Default = behind (warning triangle, amber-orange) */
  background: linear-gradient(180deg, #ffb48a 0%, var(--v2-orange) 75%);
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M12 2 1 21h22L12 2Zm0 5 7.5 13h-15L12 7Zm-1 5v4h2v-4h-2Zm0 5v2h2v-2h-2Z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M12 2 1 21h22L12 2Zm0 5 7.5 13h-15L12 7Zm-1 5v4h2v-4h-2Zm0 5v2h2v-2h-2Z'/></svg>");
  filter: drop-shadow(0 0 10px rgba(249, 115, 22, 0.55));
}
/* Ahead → upward trend arrow, green */
.pace-status:has(.pace-text.ahead) .pace-icon::after {
  background: linear-gradient(180deg, #cff9d9 0%, var(--v2-green) 75%);
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M4 18 10 12l4 4 6-8v4h2V4h-8v2h4l-4 5.3L10 7 2 15z'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M4 18 10 12l4 4 6-8v4h2V4h-8v2h4l-4 5.3L10 7 2 15z'/></svg>");
  filter: drop-shadow(0 0 10px rgba(34, 197, 94, 0.55));
}

/* ---------- 74 · PACE CARD · warmer numeric emphasis for "required avg" ---------- */

.pace-row { padding: 10px 0; }
.pace-row-label { font-size: 10.5px; letter-spacing: 2px; }
.pace-row-value {
  font-size: 22px;
  color: var(--v2-ink);
  font-weight: 700;
}
/* Semantic deltas: current avg behind target → dimmer; ahead → green already set inline */
.pace-status .pace-text.behind { color: var(--v2-orange); }
.pace-status .pace-text.ahead  { color: var(--v2-green); }

/* Fresh "CURRENT / REQUIRED" comparison — pace-card first two rows */
.pace-card .pace-row:first-of-type .pace-row-value,
.pace-card .pace-row:nth-of-type(2) .pace-row-value {
  font-family: var(--v2-font-display);
}

/* ---------- 75 · RANK GLYPH · conic halo + soft ambient shadow ---------- */

.v2-rank-glyph {
  position: relative;
  width: 88px;
  height: 88px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  filter: drop-shadow(0 10px 24px rgba(0, 0, 0, 0.4));
}
.v2-rank-glyph::before {
  content: "";
  position: absolute;
  inset: -12px;
  border-radius: 50%;
  background: conic-gradient(
    from 120deg,
    rgba(129, 140, 248, 0.00) 0deg,
    rgba(129, 140, 248, 0.22) 80deg,
    rgba(34, 211, 238, 0.18) 160deg,
    rgba(129, 140, 248, 0.00) 220deg,
    rgba(129, 140, 248, 0.00) 360deg);
  opacity: 0.55;
  z-index: 0;
  filter: blur(8px);
  animation: rankHaloRotate 18s linear infinite;
}
@keyframes rankHaloRotate {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .v2-rank-glyph::before { animation: none; }
}

/* ---------- 76 · LADDER · stronger magnetic pull on current cell ---------- */

.v2-ladder-cell.current {
  transform: translateY(-3px);
}
.v2-ladder-cell.current::after {
  /* subtle floor-glow directly beneath current cell */
  content: "";
  position: absolute;
  left: 10%; right: 10%;
  bottom: -12px;
  height: 12px;
  background: radial-gradient(ellipse 100% 100% at 50% 0%, rgba(129, 140, 248, 0.45), transparent 70%);
  pointer-events: none;
  filter: blur(3px);
}
.v2-ladder-cell.current .v2-ladder-name {
  background: linear-gradient(135deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* ---------- 77 · MODE SPLIT · thicker bars + gradient hierarchy ---------- */

.v2-mode-row .bar {
  height: 8px;
  border-radius: 1px;
}
.v2-mode-row .bar > .fill {
  border-radius: 1px;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.18) inset,
    0 0 10px var(--v2-indigo-glow);
}
.v2-mode-row.idx-1 .fill {
  background: linear-gradient(90deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.22) inset,
    0 0 10px var(--v2-indigo-glow);
}
.v2-mode-row.idx-2 .fill {
  background: linear-gradient(90deg, rgba(129, 140, 248, 0.55) 0%, rgba(129, 140, 248, 0.3) 100%);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.12) inset;
}
.v2-mode-row.idx-3 .fill {
  background: linear-gradient(90deg, rgba(129, 140, 248, 0.28) 0%, rgba(129, 140, 248, 0.12) 100%);
  box-shadow: none;
}
.v2-mode-row { margin-bottom: 16px; }
.v2-mode-row .head { margin-bottom: 8px; }
.v2-mode-row .head .stats { color: var(--v2-ink); font-weight: 700; }
.v2-mode-row.idx-2 .head .stats,
.v2-mode-row.idx-3 .head .stats { color: var(--v2-dim); font-weight: 600; }

/* ---------- 78 · ROADMAP ROW · cleaner "days" treatment ---------- */

.roadmap-row {
  padding: 11px 14px;
  border-radius: 2px;
}
.roadmap-detail { font-size: 11.5px; letter-spacing: 0.8px; }
.roadmap-row.goal {
  padding: 13px 14px;
}
.roadmap-row.goal .roadmap-name {
  background: linear-gradient(135deg, var(--v2-indigo) 0%, var(--v2-cyan) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  font-size: 19px;
}

/* ---------- 79 · MATCH BUTTONS · refined hover lift + inner glow ---------- */

.v2-match-btn {
  transition:
    transform 0.18s var(--v2-ease-emph),
    border-color 0.18s var(--v2-ease-out),
    background 0.22s var(--v2-ease-out),
    box-shadow 0.22s var(--v2-ease-out);
}
.v2-match-btn:not(.hero):hover {
  transform: translateY(-1px);
  border-color: rgba(129, 140, 248, 0.45);
  background: linear-gradient(180deg, rgba(129, 140, 248, 0.10), rgba(129, 140, 248, 0.02));
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 8px 18px -10px rgba(0, 0, 0, 0.6),
    0 0 0 1px rgba(129, 140, 248, 0.28);
}
.v2-match-btn.hero:hover {
  transform: translateY(-1px);
  filter: brightness(1.05);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.35) inset,
    0 10px 22px -8px var(--v2-green-glow),
    0 0 0 1px rgba(34, 197, 94, 0.55);
}

/* ---------- 80 · SEGMENTED TABS · active pill with shadow, cleaner indicator ---------- */

.v2-mode-tab.active {
  background: linear-gradient(180deg, rgba(129, 140, 248, 0.22), rgba(129, 140, 248, 0.10));
  color: var(--v2-ink);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 0 0 1px rgba(129, 140, 248, 0.40),
    0 6px 14px -6px var(--v2-indigo-glow);
}

/* ---------- 81 · CARD SHEEN · softer + only where it reads as premium ---------- */

.v2-card,
.roadmap-card,
.v2-week,
.v2-mode-split,
.v2-ladder-card,
.chart-card {
  /* Dial back sheen intensity; previous layer set 2.5% opacity — keep subtle */
  background-size: 240% 240%;
}
.v2-card:hover,
.roadmap-card:hover,
.v2-week:hover,
.v2-mode-split:hover,
.v2-ladder-card:hover,
.chart-card:hover {
  box-shadow: var(--v2-card-shadow-hover);
  transform: translateY(-1px);
}

/* ---------- 82 · SECTION RHYTHM · tighter main gap for denser editorial feel ---------- */

.v2-main {
  gap: 24px;      /* 28 → 24: denser broadcast rhythm */
}
@media (min-width: 1200px) {
  .v2-main {
    gap: 26px;
  }
}

/* Extra breathing between the headline block and the rest of the story */
.v2-main > div:first-child {
  margin-bottom: 4px;
}

/* ---------- 83 · CHART CARD · better typography + canvas framing ---------- */

.chart-card {
  padding: 22px 24px 16px;
}
.chart-title { font-size: 20px; letter-spacing: 0.01em; }
.chart-badge {
  padding: 4px 10px;
  background: rgba(129, 140, 248, 0.10);
  border: 1px solid rgba(129, 140, 248, 0.28);
  color: var(--v2-indigo);
  font-size: 11.5px;
  letter-spacing: 1.2px;
  border-radius: 2px;
  font-weight: 700;
}
.chart-canvas-wrapper {
  position: relative;
}
.chart-canvas-wrapper::before {
  /* subtle top fade so grid doesn't butt against the header */
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 24px;
  background: linear-gradient(180deg, rgba(16, 20, 31, 0.75), transparent);
  pointer-events: none;
  z-index: 1;
}

/* ---------- 84 · SIDEBAR · tighter top block on desktop so match-log feels primary ---------- */

@media (min-width: 961px) {
  .v2-sidebar { gap: 28px; padding: 32px 28px 28px; }
  .v2-sidebar > section + section { padding-top: 26px; }
}

/* ---------- 85 · MASTHEAD · subtle brand glow on hover ---------- */

.v2-masthead-title {
  transition: letter-spacing 0.35s var(--v2-ease-emph), filter 0.35s;
}
.v2-masthead:hover .v2-masthead-title {
  filter: drop-shadow(0 0 14px rgba(245, 166, 35, 0.35));
}

/* ---------- 86 · MOBILE · sidebar compression + match-log primacy ---------- */

@media (max-width: 960px) {
  /* Put the log match primary action above the masthead-style header so
     the first thing the user sees is what they actually do. */
  .v2-sidebar {
    gap: 14px;
    padding: 14px 16px 16px;
  }
  .v2-sidebar > section + section { padding-top: 14px; }
  .v2-sidebar > section + section::before { opacity: 0.5; }

  /* Compress masthead visual noise on mobile */
  .v2-masthead { padding-bottom: 10px; }
  .v2-masthead::after { width: 32px; height: 2px; }
  .v2-masthead-sub { font-size: 10px; letter-spacing: 1.4px; }

  /* Match-grid: tighter gaps + chunkier tap targets, 2×2 feels primary */
  .v2-match-grid { gap: 8px; }
  .v2-match-btn {
    min-height: 64px;
    padding: 10px 10px;
    border-radius: 3px;
  }
  .v2-match-btn-pts { font-size: 12px; letter-spacing: 1.4px; }
  .v2-match-btn-label { font-size: 18px; }

  /* Points input: ensure it stays a high-focus element — don't shrink below comfortable size */
  .v2-points-input { height: 58px; font-size: 36px; }
  .v2-points-step { height: 58px; width: 52px; }

  /* Goal summary row: keep the Change action on its own visual line of attention */
  .v2-goal-summary {
    padding: 10px 12px;
    min-height: 44px;
  }

  /* Today + week on mobile: slightly reduce internal gaps */
  .v2-today { padding: 14px 16px 18px; gap: 14px; }
  .v2-today .value { font-size: 24px; }
  .v2-week { padding: 16px 16px; }
  .week-day-bar { height: 56px; }

  /* Main column: single-column, preserve rhythm */
  .v2-main { gap: 18px; padding: 22px 16px calc(120px + var(--v2-safe-bottom, 0px)); }

  /* Cards: universally slightly less padding on mobile */
  .v2-card,
  .roadmap-card,
  .pace-card,
  .v2-mode-split,
  .v2-ladder-card,
  .chart-card { padding: 16px 18px; border-radius: 3px; }

  /* Rank progress card: re-stack head when glyph + text can't fit comfortably */
  .v2-rank-progress-card { padding: 18px 18px; gap: 14px; }
  .v2-rank-progress-card .v2-rank-glyph { width: 56px; height: 56px; }
  .v2-rank-progress-card .v2-rank-name { font-size: 26px; }

  /* Ladder: 2-row 3-col is cleaner than the 3-col stretched wide */
  .v2-ladder { gap: 8px; }
  .v2-ladder-cell { padding: 14px 6px 12px; }
  .v2-ladder-glyph { width: 32px; height: 32px; }
  .v2-ladder-name { font-size: 13px; }
  .v2-ladder-pts { font-size: 10px; }
}

/* ---------- 87 · MOBILE · quick-dock refinement (crisper chip, taller tap) ---------- */

@media (max-width: 960px) {
  .v2-quick-dock {
    padding: 10px 12px calc(10px + var(--v2-safe-bottom, 0px));
    gap: 8px;
  }
  .v2-quick-dock .qd-btn {
    min-height: 54px;
    padding: 8px 6px;
    border-radius: 3px;
  }
  .v2-quick-dock .qd-btn .pts { font-size: 10.5px; letter-spacing: 1.2px; }
  .v2-quick-dock .qd-btn .lbl { font-size: 16px; }

  /* Clean "QUICK LOG" chip with subtle live-dot */
  .v2-quick-dock::before {
    top: -16px;
    padding: 3px 10px 3px 18px;
    letter-spacing: 2.4px;
    font-size: 9px;
    background:
      radial-gradient(circle 3px at 9px 50%, var(--v2-cyan) 0%, var(--v2-cyan) 100%, transparent 100%),
      rgba(11, 16, 32, 0.92);
  }
  /* The dot gets a pulse */
  .v2-quick-dock::after {
    content: "";
    position: absolute;
    left: 50%;
    top: -12px;
    margin-left: -45px;
    width: 4px; height: 4px;
    border-radius: 50%;
    background: var(--v2-cyan);
    box-shadow: 0 0 0 2px rgba(34, 211, 238, 0.2), 0 0 8px var(--v2-cyan);
    animation: livePulse 2.4s ease-in-out infinite;
    pointer-events: none;
  }
  /* Press feedback → deeper scale + glow */
  .v2-quick-dock .qd-btn:active {
    transform: scale(0.92);
    filter: brightness(1.1);
  }
  .v2-quick-dock .qd-btn.win:active {
    box-shadow:
      0 1px 0 rgba(255,255,255,0.45) inset,
      0 4px 10px -4px var(--v2-green-glow),
      0 0 0 1px rgba(34, 197, 94, 0.65),
      0 0 18px var(--v2-green-glow);
  }
}

/* ---------- 88 · MOBILE · headline balance ---------- */

@media (max-width: 960px) {
  .v2-headline {
    font-size: clamp(30px, 8.8vw, 52px);
    line-height: 1.02;
    letter-spacing: -0.01em;
  }
  .v2-headline .accent-amber { padding-bottom: 4px; }
  .v2-headline .accent-amber::before { height: 2.5px; }
  .v2-headline-sub {
    font-size: 14px;
    gap: 8px;
    margin-top: 14px;
  }
}
@media (max-width: 480px) {
  .v2-headline { font-size: clamp(28px, 8.8vw, 42px); }
  .v2-headline-sub { font-size: 13px; line-height: 1.5; }
}

/* ---------- 89 · DESKTOP · chart aurora underlay for Points Over Time ---------- */

@media (min-width: 961px) {
  .chart-card-full {
    position: relative;
    overflow: hidden;
  }
  .chart-card-full::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
      radial-gradient(ellipse 80% 40% at 30% 100%, rgba(34, 211, 238, 0.06), transparent 60%),
      radial-gradient(ellipse 60% 40% at 85% 0%, rgba(129, 140, 248, 0.06), transparent 60%);
    pointer-events: none;
    z-index: 0;
  }
  .chart-card-full > * { position: relative; z-index: 1; }
}

/* ---------- 90 · FOCUS-VISIBLE · precise ring without layout shift ---------- */

:focus-visible {
  box-shadow:
    0 0 0 2px var(--v2-bg),
    0 0 0 4px rgba(129, 140, 248, 0.55),
    0 0 22px -4px var(--v2-indigo-glow);
}
/* Keep buttons precisely ringed so they don't jump */
.v2-match-btn:focus-visible,
.v2-mode-tab:focus-visible,
.v2-goal-pill:focus-visible,
.qd-btn:focus-visible,
.v2-points-step:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--v2-bg),
    0 0 0 4px rgba(129, 140, 248, 0.65),
    0 0 18px -4px var(--v2-indigo-glow);
}

/* ---------- 91 · COMPOUND · tabular numbers everywhere that's a stat ---------- */

.pace-row-value,
.roadmap-detail,
.v2-ladder-pts,
.chart-badge,
.v2-mode-row .head .stats {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ---------- 92 · TODAY · done-state green flourish ---------- */

.v2-today.done .value.green {
  animation: todayDonePulse 1.4s var(--v2-ease-emph) 1;
}
@keyframes todayDonePulse {
  0%   { transform: scale(1); text-shadow: 0 0 18px var(--v2-green-glow); }
  40%  { transform: scale(1.04); text-shadow: 0 0 28px var(--v2-green-glow); }
  100% { transform: scale(1); text-shadow: 0 0 18px var(--v2-green-glow); }
}
@media (prefers-reduced-motion: reduce) {
  .v2-today.done .value.green { animation: none; }
}

/* ---------- 93 · LAST-UPDATED · align with new rhythm ---------- */

.last-updated {
  font-size: 9.5px;
  letter-spacing: 1.4px;
}

/* ============================================================
   POLISH LAYER v5.5 — iteration
   Focus: fix QUICK LOG chip duplication, tighten mobile density,
   improve mode-split 100% state, refine today-bar reverse layout,
   add subtle desktop micro-interactions on the rank card.
   ============================================================ */

/* ---------- 94 · QUICK LOG chip · clean single-dot pattern ---------- */

@media (max-width: 960px) {
  /* Reset v87 background to a clean pill — live dot owned by ::after only */
  .v2-quick-dock::before {
    padding: 3px 10px 3px 20px;
    background: rgba(11, 16, 32, 0.94);
    box-shadow: 0 -4px 10px -4px rgba(0, 0, 0, 0.4);
  }
  .v2-quick-dock::after {
    /* Anchor dot to the chip by using the same x% center origin */
    left: 50%;
    top: -10px;
    margin-left: -28px; /* aligns inside chip's left padding */
    width: 5px; height: 5px;
  }
}

/* ---------- 95 · MOBILE sidebar compression pass 2 ---------- */

@media (max-width: 960px) {
  /* Masthead even tighter on narrow */
  .v2-masthead { border-bottom-width: 1.5px; }

  /* Sync row: reduce padding, add slim tier-aware accent */
  .v2-sync { padding: 10px 12px; font-size: 10.5px; }
  .v2-sync-action { padding: 6px 10px; font-size: 10px; }

  /* Undo button: keep it a chip, not a full-width bar */
  .v2-undo {
    margin: 6px auto 0;
    width: auto;
    padding: 8px 18px;
    font-size: 10px;
  }

  /* Current Points: size down for mobile, input stays tappable */
  .v2-points-input { height: 54px; font-size: 34px; }
  .v2-points-step { height: 54px; width: 48px; font-size: 24px; }
  .v2-points-meta { margin-top: 8px; font-size: 11px; }

  /* Goal summary line tighter */
  .v2-goal-summary-name { font-size: 14px; }
  .v2-goal-summary-remain { font-size: 11px; }
  .v2-goal-summary-action { font-size: 10px; }
}

/* ---------- 96 · TODAY BAR · fix reverse-row layout on mobile ---------- */

@media (max-width: 720px) {
  /* Undo the desktop reverse-row treatment; stacks feel more natural tight */
  .v2-today .group.right { flex-direction: row; gap: 10px; }
  .v2-today .group.right .label { text-align: right; }
  .v2-today { gap: 10px; padding: 14px 16px 16px; }
  .v2-today .value { font-size: 22px; }
  .v2-today .label { font-size: 9.5px; letter-spacing: 1.8px; }
}

/* ---------- 97 · MODE SPLIT · "100%" champion highlight ---------- */

.v2-mode-row.idx-1 .head .stats {
  color: var(--v2-cyan);
  text-shadow: 0 0 10px rgba(34, 211, 238, 0.35);
}
/* When a single mode holds 100%, the fill glows more brightly */
.v2-mode-row.idx-1[data-pct="100"] .fill,
.v2-mode-row.idx-1 .fill[style*="width: 100%"] {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.28) inset,
    0 0 14px var(--v2-indigo-glow),
    0 0 20px rgba(34, 211, 238, 0.32);
}

/* ---------- 98 · RANK CARD · subtle scanning highlight on hover ---------- */

@media (min-width: 961px) {
  .v2-rank-progress-card {
    position: relative;
    overflow: hidden;
  }
  .v2-rank-progress-card::after {
    content: "";
    position: absolute;
    top: 0; bottom: 0;
    left: -40%;
    width: 30%;
    background: linear-gradient(100deg,
      transparent 0%,
      rgba(129, 140, 248, 0.05) 50%,
      transparent 100%);
    transform: skewX(-18deg);
    transition: left 0.9s var(--v2-ease-emph);
    pointer-events: none;
    z-index: 1;
  }
  .v2-rank-progress-card:hover::after {
    left: 120%;
  }
  .v2-rank-progress-card > * {
    position: relative;
    z-index: 2;
  }
}

/* ---------- 99 · HEADLINE sub · chip tone calibrations ---------- */

.v2-pace-chip.is-behind {
  color: #ff9b6f;
  border-color: rgba(249, 115, 22, 0.40);
  background: linear-gradient(180deg, rgba(249, 115, 22, 0.14), rgba(249, 115, 22, 0.06));
  box-shadow: 0 0 10px -2px rgba(249, 115, 22, 0.25) inset;
}
.v2-pace-chip.is-on {
  color: var(--v2-cyan);
  border-color: rgba(34, 211, 238, 0.40);
  background: linear-gradient(180deg, rgba(34, 211, 238, 0.14), rgba(34, 211, 238, 0.06));
  box-shadow: 0 0 10px -2px rgba(34, 211, 238, 0.25) inset;
}
.v2-pace-chip.is-ahead {
  color: #6ee7b7;
  border-color: rgba(110, 231, 183, 0.45);
  background: linear-gradient(180deg, rgba(34, 197, 94, 0.14), rgba(34, 197, 94, 0.06));
  box-shadow: 0 0 10px -2px rgba(34, 197, 94, 0.25) inset;
}

/* ---------- 100 · LADDER · fluid current → passed gradient band ---------- */

.v2-ladder-card {
  position: relative;
  overflow: hidden;
}
.v2-ladder-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg,
    #c87533 0%,
    #c0c7d4 20%,
    #f5c73a 40%,
    #8dd8e8 60%,
    #b5baff 80%,
    #3ed39d 100%);
  opacity: 0.45;
  pointer-events: none;
}

/* ---------- 101 · ROADMAP GOAL ROW · gradient underline on name ---------- */

.roadmap-row.goal .roadmap-name {
  position: relative;
}
.roadmap-row.goal .roadmap-name::after {
  content: "";
  display: block;
  margin-top: 2px;
  height: 2px;
  width: 42px;
  background: linear-gradient(90deg, var(--v2-indigo), var(--v2-cyan));
  border-radius: 1px;
  box-shadow: 0 0 8px var(--v2-indigo-glow);
  opacity: 0.7;
}

/* ---------- 102 · MOBILE · main content top breathing room ---------- */

@media (max-width: 960px) {
  /* Small divider between sidebar's sync row and main headline for clarity */
  .v2-main { padding-top: 24px; position: relative; }
  .v2-main::before {
    content: "";
    position: absolute;
    left: 16px; right: 16px;
    top: 12px;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(129, 140, 248, 0.30), transparent);
    pointer-events: none;
  }
}

/* ---------- 103 · MOBILE · headline first-line protection ---------- */

@media (max-width: 480px) {
  /* Shrink accent-pace "PTS/DAY" so the headline stays 2-3 tight lines */
  .v2-headline .accent-pace { font-size: 0.9em; }
  .v2-headline .accent-amber { padding-bottom: 3px; }
}

/* ---------- 104 · DESKTOP · add sticky-ish feel to "TODAY" value ---------- */

@media (min-width: 961px) {
  .v2-today .value.green:not(.zero) {
    position: relative;
  }
  .v2-today .value.green:not(.zero)::before {
    content: "";
    position: absolute;
    left: -8px; right: -8px;
    top: 50%;
    height: 22px;
    margin-top: -11px;
    background: radial-gradient(ellipse 60% 100% at 50% 50%, rgba(34, 197, 94, 0.18), transparent 70%);
    filter: blur(4px);
    z-index: -1;
    pointer-events: none;
  }
}

/* ---------- 105 · FOOTER · brand typographic tightening ---------- */

.page-footer { font-size: 12px; }
.page-footer p { margin: 4px 0; }
.footer-links { gap: 14px; font-size: 9.5px; letter-spacing: 1.3px; }
@media (max-width: 480px) {
  .page-footer { padding: 20px 16px calc(40px + var(--v2-safe-bottom, 0px)); font-size: 11.5px; }
  .footer-links { gap: 10px 14px; }
}

/* ============================================================
   POLISH LAYER v6 — Pass 2 · editorial hierarchy elevation
   Focus: filler-word dimming, DONE chip, tier visibility,
   section-label wayfinders, meta diamond refinement.
   ============================================================ */

/* ---------- 106 · HEADLINE · dim non-data filler words ----------
   "YOU NEED [25 PTS/DAY] TO HIT [EMERALD I] BY [JUL 8]."
   Filler ("YOU NEED", "TO HIT", "BY") should sit back so the data reads first.
   We target direct text of .v2-headline that isn't inside a colored accent,
   using `color` + a class boost on accents to outrank it. */

.v2-headline {
  color: rgba(245, 247, 251, 0.72); /* filler */
}
.v2-headline .accent-pace,
.v2-headline .accent-date,
.v2-headline .accent-amber,
.v2-headline .accent-crimson {
  /* each accent keeps its bright treatment */
}
.v2-headline .accent-amber {
  color: var(--v2-ink); /* the gradient clip keeps text transparent; this is fallback */
}
/* The trailing dot should match the brightest tone for sentence closure */
.v2-headline .dot {
  color: rgba(245, 247, 251, 0.72);
  -webkit-text-fill-color: rgba(245, 247, 251, 0.72);
}

/* Accent-date gets a touch more brightness for balance with accent-pace */
.v2-headline .accent-date {
  color: var(--v2-ink);
  border-bottom-color: rgba(129, 140, 248, 0.65);
}

/* ---------- 107 · DONE-FOR-TODAY · replace ✅ emoji with a CSS check chip ---------- */
/* Tracker injects the green check square emoji when the day's target is met.
   Hide the emoji and render a clean glyph in its place. */

.v2-today .value.green:not(.zero) + .value,
.v2-today .group:last-child .value {
  position: relative;
}

/* Hide any emoji checkmark the tracker writes, and inject our own */
.v2-today .group:last-child .value {
  /* Do nothing by default — only transform when goal met */
}
.v2-today.done .group:last-child .value {
  font-size: 0;
  color: transparent;
  display: inline-flex;
  align-items: center;
  width: 26px;
  height: 26px;
  background: linear-gradient(180deg, var(--v2-green-warm), var(--v2-green));
  border-radius: 50%;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.35) inset,
    0 4px 10px -4px var(--v2-green-glow),
    0 0 0 2px rgba(34, 197, 94, 0.30);
}
.v2-today.done .group:last-child .value::before {
  content: "";
  width: 14px; height: 14px;
  background: #06210f;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M9 16.2 4.8 12l-1.4 1.4L9 19l12-12-1.4-1.4z'/></svg>") center/contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M9 16.2 4.8 12l-1.4 1.4L9 19l12-12-1.4-1.4z'/></svg>") center/contain no-repeat;
  margin: auto;
}

/* ---------- 108 · SECTION LABELS · right-side fading hairline ---------- */
/* Turns every editorial card header into a "chapter divider" — indicator dot,
   label text, and then a fading hairline filling the remaining row. */

.v2-card > .v2-section-label,
.roadmap-card > .v2-section-label,
.v2-week .v2-week-header,
.chart-card .chart-header,
.v2-mode-split > .v2-section-label,
.v2-ladder-card > .v2-section-label,
.roadmap-card .roadmap-header {
  position: relative;
}

/* Roadmap header has no flexbox wrapper — give it the label styling too */
.roadmap-header {
  display: flex;
  align-items: center;
  gap: 10px;
}
.roadmap-header::before {
  content: "";
  width: 8px; height: 2px;
  background: linear-gradient(90deg, var(--v2-indigo), var(--v2-cyan));
  box-shadow: 0 0 8px rgba(129, 140, 248, 0.6);
  flex-shrink: 0;
}
.roadmap-header::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(129, 140, 248, 0.18) 0%, transparent 70%);
  margin-left: 4px;
}

/* Add trailing hairline to v2-section-label so its flex end always terminates with a thread */
.v2-section-label {
  position: relative;
}
.v2-section-label::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 100%;
  margin-top: 10px;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(129, 140, 248, 0.10) 15%,
    rgba(129, 140, 248, 0.10) 85%,
    transparent 100%);
  opacity: 0;
  pointer-events: none;
}
/* Only show under main-content card labels (not in sidebar) */
.v2-main .v2-section-label::after,
.chart-card .chart-header::after {
  opacity: 1;
}
/* Reset for section-labels that are inline (like inside rank card's head) */
.v2-rank-progress-head .v2-section-label::after,
.v2-mode-split > .v2-section-label::after,
.v2-ladder-card > .v2-section-label::after { display: none; }

/* ---------- 109 · LADDER · future-tier visibility bump + name glow ---------- */

.v2-ladder-cell:not(.passed):not(.current) {
  opacity: 0.62;      /* 0.45 → 0.62 — readable but still secondary */
  border-color: rgba(255, 255, 255, 0.04);
}
.v2-ladder-cell:not(.passed):not(.current):hover {
  opacity: 0.85;
  border-color: color-mix(in srgb, currentColor 30%, transparent);
  transform: translateY(-1px);
  background: linear-gradient(180deg, color-mix(in srgb, currentColor 6%, transparent), transparent);
}
.v2-ladder-cell:not(.passed):not(.current) .v2-ladder-name {
  color: color-mix(in srgb, currentColor 70%, var(--v2-dim));
}
.v2-ladder-cell.passed {
  opacity: 0.92;
}
.v2-ladder-cell.passed .v2-ladder-name {
  color: color-mix(in srgb, currentColor 75%, var(--v2-ink));
}

/* ---------- 110 · SYNC DOT · ambient pulse + sharper tiers ---------- */

.v2-sync .dot {
  background: radial-gradient(circle at 40% 40%, #f5c43a 0%, #d98f1c 70%, #8a5711 100%);
  box-shadow: 0 0 0 2px rgba(245, 166, 35, 0.2), 0 0 8px rgba(245, 166, 35, 0.5);
  animation: syncDotPulseAmber 2.6s ease-in-out infinite;
}
.v2-sync.logged-in .dot {
  background: radial-gradient(circle at 40% 40%, #a7f0b7 0%, var(--v2-green) 70%, #186637 100%);
  box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.2), 0 0 8px rgba(34, 197, 94, 0.5);
  animation: syncDotPulseGreen 2.6s ease-in-out infinite;
}
@keyframes syncDotPulseAmber {
  0%, 100% { box-shadow: 0 0 0 2px rgba(245, 166, 35, 0.15), 0 0 6px rgba(245, 166, 35, 0.45); }
  50%      { box-shadow: 0 0 0 4px rgba(245, 166, 35, 0.05), 0 0 12px rgba(245, 166, 35, 0.65); }
}
@keyframes syncDotPulseGreen {
  0%, 100% { box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.15), 0 0 6px rgba(34, 197, 94, 0.45); }
  50%      { box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.05), 0 0 12px rgba(34, 197, 94, 0.65); }
}
@media (prefers-reduced-motion: reduce) {
  .v2-sync .dot { animation: none; }
}

/* ---------- 111 · ROADMAP · "N more ranks" as a quiet chip ---------- */

.roadmap-skip {
  display: inline-flex;
  align-self: center;
  padding: 4px 14px;
  margin: 2px auto;
  border-radius: 999px;
  background: rgba(129, 140, 248, 0.06);
  border: 1px dashed rgba(129, 140, 248, 0.22);
  color: var(--v2-dim);
  font-size: 10.5px;
  letter-spacing: 1.5px;
  font-weight: 600;
  text-transform: uppercase;
}

/* ---------- 112 · META DIAMOND · precision balance ---------- */

.v2-pace-meta .current {
  font-weight: 700;
}
.v2-pace-meta .current::before {
  font-size: 8px;
  transform: translateY(-1px);
  margin-right: 5px;
}

/* ---------- 113 · MODE SPLIT TITLE · accent underline ---------- */

.v2-mode-split-title {
  position: relative;
  display: inline-block;
  padding-bottom: 6px;
  margin-bottom: 16px;
}
.v2-mode-split-title::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 36px;
  height: 2px;
  background: linear-gradient(90deg, var(--v2-indigo), var(--v2-cyan));
  border-radius: 1px;
  box-shadow: 0 0 8px var(--v2-indigo-glow);
  opacity: 0.75;
}

/* ---------- 114 · MATCH BUTTONS · label contrast on hero WIN ---------- */

.v2-match-btn.hero .v2-match-btn-label {
  color: #06210f;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
  letter-spacing: 0.04em;
}
.v2-match-btn.hero .v2-match-btn-pts {
  color: rgba(6, 33, 15, 0.75);
  font-weight: 800;
  letter-spacing: 1.4px;
}

/* ---------- 115 · POINTS BY MODE · rank chip on each row ---------- */
/* Not critical but refines the head — add a tiny numeric ordinal */

.v2-mode-row .head .label {
  position: relative;
  padding-left: 18px;
}
.v2-mode-row.idx-1 .head .label::before,
.v2-mode-row.idx-2 .head .label::before,
.v2-mode-row.idx-3 .head .label::before {
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%);
  font-family: var(--v2-font-mono);
  font-size: 9.5px;
  letter-spacing: 0.5px;
  font-weight: 800;
  padding: 1px 4px;
  border-radius: 2px;
  line-height: 1;
}
.v2-mode-row.idx-1 .head .label::before {
  content: "1";
  background: linear-gradient(180deg, var(--v2-indigo), var(--v2-indigo-deep));
  color: #fff;
  box-shadow: 0 0 6px var(--v2-indigo-glow);
}
.v2-mode-row.idx-2 .head .label::before {
  content: "2";
  background: rgba(129, 140, 248, 0.25);
  color: var(--v2-ink);
}
.v2-mode-row.idx-3 .head .label::before {
  content: "3";
  background: rgba(129, 140, 248, 0.12);
  color: var(--v2-dim);
}

/* ---------- 116 · CHARTS TEASER · refined button + headline hierarchy ---------- */

.charts-teaser {
  padding: 28px 28px 32px;
}
.charts-teaser-content h3 {
  font-family: var(--v2-font-display);
  letter-spacing: 0.02em;
  background: linear-gradient(135deg, var(--v2-ink) 0%, #b5bcd8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.charts-teaser-content p {
  color: var(--v2-dim);
  font-size: 13.5px;
  letter-spacing: 0.2px;
}
.discord-btn {
  background: linear-gradient(180deg, #6366f1 0%, #4f46e5 100%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.2) inset,
    0 8px 18px -6px rgba(99, 102, 241, 0.55),
    0 0 0 1px rgba(99, 102, 241, 0.6);
  transition: transform 0.15s var(--v2-ease-emph), box-shadow 0.2s var(--v2-ease-out), filter 0.2s;
}
.discord-btn:hover {
  transform: translateY(-1px);
  filter: brightness(1.08);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.28) inset,
    0 10px 22px -6px rgba(99, 102, 241, 0.65),
    0 0 0 1px rgba(99, 102, 241, 0.75);
}

/* ---------- 117 · GOAL PILL · winner state glow when selected ---------- */

.v2-goal-pill.active {
  border-color: var(--v2-indigo);
  background: linear-gradient(180deg, rgba(129, 140, 248, 0.28), rgba(129, 140, 248, 0.08));
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 0 0 1px rgba(129, 140, 248, 0.45),
    0 8px 20px -8px var(--v2-indigo-glow);
  color: var(--v2-ink);
}

/* ---------- 118 · ROADMAP · reveal "on target" vs "overdue" via detail color ---------- */

.roadmap-row .roadmap-detail {
  font-variant-numeric: tabular-nums;
}

/* ---------- 119 · TODAY · zero-state ghost text for "pts left today" ---------- */

.v2-today[data-empty="true"] .group:last-child .value {
  color: var(--v2-dim);
}
.v2-today[data-empty="true"] .group:last-child .label {
  color: var(--v2-faint);
}

/* ---------- 120 · CURRENT-POINTS METADATA · align percentage cue ---------- */

.v2-points-meta .pct {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1px;
  padding: 2px 8px;
  background: rgba(129, 140, 248, 0.08);
  border-radius: 2px;
  border: 1px solid rgba(129, 140, 248, 0.18);
}
.v2-points-meta .pct::before {
  content: "●";
  color: var(--v2-indigo);
  font-size: 7px;
  margin-right: 4px;
  vertical-align: middle;
  filter: drop-shadow(0 0 4px var(--v2-indigo-glow));
}

/* ============================================================
   POLISH LAYER v7 — Pass 3 · lived-in choreography + micro-details
   Focus: scroll-linked aurora, week-day peak medal, last-updated pill,
   ladder hover lift, entrance stagger, celebratory done-state details.
   ============================================================ */

/* ---------- 121 · LAST-UPDATED · micro-pill with live-feel ---------- */

.last-updated {
  padding: 5px 12px 5px 22px;
  background: rgba(11, 16, 32, 0.85);
  backdrop-filter: blur(8px) saturate(1.2);
  -webkit-backdrop-filter: blur(8px) saturate(1.2);
  border: 1px solid rgba(129, 140, 248, 0.18);
  border-radius: 999px;
  position: fixed;
  bottom: 16px;
  right: 140px;
  color: var(--v2-dim);
  z-index: 56;
  pointer-events: auto;
  transition: border-color 0.2s, color 0.2s, transform 0.2s;
}
.last-updated::before {
  content: "";
  position: absolute;
  left: 10px; top: 50%;
  transform: translateY(-50%);
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--v2-cyan);
  box-shadow: 0 0 0 2px rgba(34, 211, 238, 0.2), 0 0 6px var(--v2-cyan);
  animation: livePulse 2.4s ease-in-out infinite;
}
.last-updated:hover {
  border-color: rgba(129, 140, 248, 0.35);
  color: var(--v2-ink);
}
@media (max-width: 960px) {
  .last-updated { display: none; }
}

/* ---------- 122 · LADDER CELL · hover lift for non-current tiers ---------- */

.v2-ladder-cell:not(.current) {
  transition: opacity 0.22s var(--v2-ease-out),
              border-color 0.22s var(--v2-ease-out),
              background 0.22s var(--v2-ease-out),
              transform 0.22s var(--v2-ease-out),
              box-shadow 0.22s var(--v2-ease-out);
}
.v2-ladder-cell.passed:hover {
  transform: translateY(-1px);
  opacity: 1;
  box-shadow: 0 8px 18px -8px color-mix(in srgb, currentColor 45%, transparent);
}
.v2-ladder-cell .v2-ladder-glyph {
  transition: transform 0.22s var(--v2-ease-emph), filter 0.22s var(--v2-ease-out);
}
.v2-ladder-cell:hover .v2-ladder-glyph {
  transform: translateY(-2px) scale(1.04);
}

/* ---------- 123 · WEEK DAY · peak-day crown + today marker dot ---------- */

.week-day {
  /* Reserve space for crown indicator above top of bar */
}
.week-day-bar {
  position: relative;
}
.week-day.peak .week-day-bar::after {
  content: "";
  position: absolute;
  top: -10px;
  left: 50%;
  transform: translateX(-50%);
  width: 0; height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid var(--v2-indigo);
  filter: drop-shadow(0 0 5px var(--v2-indigo-glow));
  pointer-events: none;
}
.week-day.today::before {
  /* subtle "today" tag floating above the day label */
  content: "TODAY";
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: -18px;
  font-family: var(--v2-font-mono);
  font-size: 8.5px;
  letter-spacing: 1.4px;
  font-weight: 800;
  color: var(--v2-indigo);
  opacity: 0;
  transition: opacity 0.25s;
}
.week-day.today:hover::before {
  opacity: 1;
}

/* ---------- 124 · ENTRANCE CHOREOGRAPHY · stagger across main sections ---------- */

.v2-main > * {
  opacity: 0;
  transform: translate3d(0, 10px, 0);
  animation: sectionRise 0.6s var(--v2-ease-emph) both;
}
.v2-main > *:nth-child(1) { animation-delay: 0.05s; }
.v2-main > *:nth-child(2) { animation-delay: 0.12s; }
.v2-main > *:nth-child(3) { animation-delay: 0.18s; }
.v2-main > *:nth-child(4) { animation-delay: 0.24s; }
.v2-main > *:nth-child(5) { animation-delay: 0.30s; }
.v2-main > *:nth-child(6) { animation-delay: 0.36s; }
.v2-main > *:nth-child(7) { animation-delay: 0.42s; }
.v2-main > *:nth-child(8) { animation-delay: 0.48s; }

@keyframes sectionRise {
  0%   { opacity: 0; transform: translate3d(0, 10px, 0); }
  100% { opacity: 1; transform: translate3d(0, 0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .v2-main > * {
    opacity: 1;
    transform: none;
    animation: none;
  }
}

/* ---------- 125 · TODAY DONE · celebratory confetti spark line ---------- */

.v2-today.done::before {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: -1px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--v2-green), transparent);
  opacity: 0;
  animation: doneSparkLine 1.8s var(--v2-ease-out) 0.2s both;
}
@keyframes doneSparkLine {
  0%   { opacity: 0; transform: scaleX(0.4); }
  40%  { opacity: 0.95; transform: scaleX(1); }
  100% { opacity: 0; transform: scaleX(1); }
}
@media (prefers-reduced-motion: reduce) {
  .v2-today.done::before { animation: none; opacity: 0; }
}

/* ---------- 126 · SCROLL-LINKED AURORA · parallax backdrop ---------- */
/* Modern browsers get scroll-timeline; legacy browsers get the existing static aurora */

@supports (animation-timeline: scroll()) {
  .v2-main::after {
    animation: auroraParallax linear both;
    animation-timeline: scroll(root);
    animation-range: 0 100vh;
  }
  @keyframes auroraParallax {
    0%   { transform: translate3d(0, 0, 0) scale(1); opacity: 0.95; }
    100% { transform: translate3d(-3%, 8%, 0) scale(1.08); opacity: 1; }
  }
}

/* ---------- 127 · PACE BAR KNOB · precision data-tag on hover ---------- */
/* Already set in layer 56 — refine the tag so it reads like a data chip. */

.v2-pace-bar:hover .knob::before {
  background: linear-gradient(180deg, rgba(26, 31, 48, 0.96), rgba(16, 20, 31, 0.96));
  border: 1px solid rgba(129, 140, 248, 0.45);
  letter-spacing: 1.4px;
  font-size: 10px;
  padding: 5px 9px;
  font-weight: 700;
  text-transform: uppercase;
  box-shadow: 0 8px 20px -6px rgba(0, 0, 0, 0.7), 0 0 20px -6px var(--v2-indigo-glow);
}

/* ---------- 128 · CONTENT FIRST-PAINT · smoother reveal for rank card ---------- */

.v2-rank-progress-card {
  position: relative;
  overflow: hidden;
}
.v2-rank-progress-card::before {
  content: "";
  position: absolute;
  left: 0; top: 0; right: 0; height: 100%;
  background: linear-gradient(180deg,
    rgba(129, 140, 248, 0.06) 0%,
    transparent 40%);
  pointer-events: none;
  z-index: 0;
}
.v2-rank-progress-card > * {
  position: relative;
  z-index: 2;
}

/* ---------- 129 · ROADMAP SKIP · improved hover + positioning ---------- */

.roadmap-skip {
  transition: border-color 0.18s, color 0.18s, background 0.18s;
}
.roadmap-track:hover .roadmap-skip {
  border-color: rgba(129, 140, 248, 0.35);
  color: var(--v2-ink);
  background: rgba(129, 140, 248, 0.10);
}

/* ---------- 130 · DESKTOP · sidebar top fade stays crisp on scroll ---------- */

@media (min-width: 961px) {
  .v2-sidebar {
    /* Ensure sticky cockpit stays legible as content scrolls behind */
    backdrop-filter: blur(0); /* enable safely if needed */
  }
}

/* ---------- 131 · MATCH BUTTONS · coin-flick ripple on press ---------- */

.v2-match-btn {
  position: relative;
  overflow: hidden;
}
.v2-match-btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at center, rgba(129, 140, 248, 0.35), transparent 60%);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.35s var(--v2-ease-out), transform 0.35s var(--v2-ease-out);
  pointer-events: none;
}
.v2-match-btn:active::after {
  opacity: 1;
  transform: scale(1);
  transition: opacity 0.05s, transform 0.05s;
}
.v2-match-btn.hero::after {
  background: radial-gradient(circle at center, rgba(255, 255, 255, 0.45), transparent 60%);
}

/* ---------- 132 · COUNTDOWN PILL · tactile press + shadow depth ---------- */

.v2-countdown-pill {
  cursor: default;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.5) inset,
    0 4px 12px -4px var(--v2-amber-glow),
    0 0 0 1px rgba(245, 166, 35, 0.35);
}

/* ---------- 133 · SCROLL INDICATOR (desktop) · sidebar bottom cue ---------- */
/* When user is on desktop with a lot of main content below the fold, add a
   soft bottom-fade to the sticky cockpit so it feels connected to the scroll. */

@media (min-width: 961px) {
  .v2-sidebar::before {
    height: 48px;
  }
  .v2-sidebar {
    /* subtle bottom glow inside the cockpit so it feels "alive" */
  }
}

/* ---------- 134 · TODAY BAR · amount-color interaction hint ---------- */

.v2-today:not(.done):not([data-empty="true"]) .value.green:not(.zero) {
  position: relative;
}
.v2-today:not(.done):not([data-empty="true"]) .value.green:not(.zero)::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -4px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--v2-green), transparent);
  opacity: 0.55;
}

/* ---------- 135 · ACCENT-DATE · hover-style readable underline ---------- */

.v2-headline .accent-date {
  transition: border-color 0.3s, color 0.3s;
  padding-bottom: 2px;
}

/* ---------- 136 · GOAL SUMMARY · better press feedback ---------- */

.v2-goal-summary {
  transition: background 0.2s, border-color 0.2s, transform 0.1s;
}
.v2-goal-summary:hover {
  background: rgba(129, 140, 248, 0.06);
}
.v2-goal-summary:active {
  transform: scale(0.995);
}

/* ---------- 137 · HEADLINE · size now lives in base rule (was a 961–1200 override) ---------- */

/* ---------- 138 · POINTS INPUT focus · cleaner breathing ---------- */

.v2-points-input-wrap:focus-within {
  animation: none; /* suppress any inherited pulse so the focus ring reads clearly */
}
.v2-points-input-wrap:focus-within::after {
  box-shadow: 0 0 0 2px var(--v2-indigo), 0 0 24px rgba(129, 140, 248, 0.45);
}

/* ---------- 139 · GENERAL · smooth all link/button color transitions ---------- */

a, button {
  transition-property: color, background, border-color, transform, box-shadow, filter;
  transition-duration: 0.18s;
  transition-timing-function: var(--v2-ease-out);
}

/* ---------- 140 · FINAL · ensure no scrollbar jumps on hover transforms ---------- */

.v2-main > * { will-change: opacity, transform; }
@media (prefers-reduced-motion: reduce) {
  .v2-main > * { will-change: auto; }
}

/* ============================================================
   CALM PASS — readability & restraint
   Last-cascade overrides to: bump body/label sizes, simplify
   the seasonal headline to one accent color, soften the dozen
   glows, and reduce font-family mixing. Keeps a single focal
   gradient on the daily-target hero number; everything else
   should read like editorial UI, not a casino HUD.
   ============================================================ */

/* — Section labels: bigger, less mono shouting, no glowing dot — */
.v2-section-label,
.roadmap-header,
.chart-title,
.v2-week-header .title {
  font-family: var(--v2-font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 1.2px;
  color: var(--v2-dim);
}
.v2-section-label > span:first-child::before,
.roadmap-header::before {
  box-shadow: none !important;
}
.v2-sidebar .v2-section-label {
  font-size: 13px;
  letter-spacing: 1.2px;
}
.v2-sidebar .v2-section-label .meta {
  font-size: 12px;
  letter-spacing: 0.6px;
  text-transform: none;
  font-weight: 500;
}

/* — Pace-card KPI labels: bigger, calmer — */
.pace-row-label {
  font-family: var(--v2-font-body) !important;
  font-size: 12.5px !important;
  letter-spacing: 1px !important;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--v2-dim);
}
.pace-row-value {
  font-size: 22px !important;
}

/* — "Behind pace / Ahead" status: keep semantic color, no glow — */
.pace-text {
  font-size: 24px;
  text-shadow: none !important;
  letter-spacing: 0.02em;
}
.pace-text.behind { color: #f59e7a; }   /* warmer, less neon orange */
.pace-text.ahead  { color: #6ee7b7; }
.pace-icon { font-size: 22px; opacity: 0.85; }
.pace-sub { font-size: 14px; }

/* — Demoted seasonal headline: single accent color, no gradients/glows — */
.v2-headline { color: var(--v2-dim); opacity: 1; }
.v2-headline .accent-pace {
  color: var(--v2-ink) !important;
  font-weight: 700 !important;
  text-shadow: none !important;
}
.v2-headline .accent-amber {
  background: none !important;
  -webkit-background-clip: initial !important;
  background-clip: initial !important;
  -webkit-text-fill-color: var(--v2-indigo) !important;
  color: var(--v2-indigo) !important;
  filter: none !important;
  text-decoration: none !important;
}
.v2-headline .accent-crimson {
  text-shadow: none !important;
  color: #f59e7a !important;
}
.v2-headline .accent-date {
  border-bottom: none !important;
  color: var(--v2-ink) !important;
  font-weight: 600;
}
.v2-headline-sub {
  font-size: 14px;
  color: var(--v2-dim);
}
.v2-pace-chip {
  text-transform: uppercase;
  letter-spacing: 1px;
  font-weight: 600;
}

/* — Daily-target hero: keep gradient (one focal point) but soften the glow — */
.v2-dt-num {
  filter: drop-shadow(0 3px 14px rgba(129, 140, 248, 0.18)) !important;
}
.v2-dt-hero.done .v2-dt-num,
.v2-dt-hero.won .v2-dt-num {
  filter: drop-shadow(0 3px 14px rgba(63, 215, 154, 0.18)) !important;
}
.v2-dt-eyebrow {
  font-family: var(--v2-font-body);
  font-size: 13px;
  letter-spacing: 1.2px;
  font-weight: 600;
  color: var(--v2-dim);
}
.v2-dt-paths-label {
  font-family: var(--v2-font-body);
  font-size: 13px;
  letter-spacing: 1px;
  font-weight: 600;
  color: var(--v2-dim);
}
.v2-dt-row .mode {
  font-family: var(--v2-font-body);
  font-size: 12.5px;
  letter-spacing: 0.8px;
  font-weight: 600;
}
.v2-dt-row .action { font-size: 16px; }
.v2-dt-row .total { font-size: 15px; }
.v2-dt-bank { font-size: 14px; }

/* — Pace bar: softer glows; numbers stay legible — */
.v2-pace-bar .fill {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.20) inset,
    0 0 6px rgba(129, 140, 248, 0.16) !important;
}
.v2-pace-bar.behind .fill {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.20) inset,
    0 0 6px rgba(249, 115, 22, 0.16) !important;
}
.v2-pace-bar.met .fill,
.v2-pace-bar.ahead .fill {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.20) inset,
    0 0 6px rgba(63, 215, 154, 0.16) !important;
}
.v2-pace-bar .knob {
  box-shadow:
    0 0 0 1px var(--v2-indigo),
    0 0 0 3px rgba(129, 140, 248, 0.18),
    0 0 6px rgba(129, 140, 248, 0.18) !important;
}
.v2-pace-bar.behind .knob {
  box-shadow:
    0 0 0 1px var(--v2-orange),
    0 0 0 3px rgba(249, 115, 22, 0.18),
    0 0 6px rgba(249, 115, 22, 0.18) !important;
}
.v2-pace-meta { font-size: 13px; }
.v2-pace-meta .current { font-size: 14px; }
.v2-pace-bar .pace-marker-label { font-size: 10.5px; letter-spacing: 0.8px; }

/* — Rank glyph: calmer halo, smaller drop-shadow — */
.v2-rank-glyph {
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.35)) !important;
}
.v2-rank-glyph::before {
  opacity: 0.32 !important;
}
.v2-rank-name { letter-spacing: 0.01em; }
.v2-rank-next { font-size: 14px; }

/* — Roadmap milestone text: bump body sizing — */
.roadmap-card .milestone-name,
.roadmap-card .milestone-meta,
.milestone-item .name,
.milestone-item .meta {
  font-size: 13.5px;
}
.roadmap-card { padding-top: 22px; }

/* — Today/Pts-left chip on the rank card eyebrow — — */
.v2-section-label .meta { font-size: 12.5px; letter-spacing: 0.6px; }

/* — Atmospheric backdrop: dial intensity down — — */
body::after {
  background:
    radial-gradient(ellipse 1200px 700px at 80% -10%, rgba(99, 102, 241, 0.06), transparent 60%),
    radial-gradient(ellipse 900px 600px at -10% 30%, rgba(34, 211, 238, 0.04), transparent 60%) !important;
}

/* — Mobile: keep label bumps from getting lost on narrow screens — */
@media (max-width: 720px) {
  .v2-section-label,
  .roadmap-header,
  .chart-title,
  .v2-dt-eyebrow,
  .v2-dt-paths-label { font-size: 12.5px; }
  .pace-row-label { font-size: 12px !important; }
  .pace-text { font-size: 22px; }
}

/* ============================================================
   CALM PASS — round 2: legibility for tiny info that matters.
   Sidebar goal summary, pace-bar tier labels, and the
   "you're SO close" treatment for the nearest milestone.
   ============================================================ */

/* — Sidebar goal summary row: was 10.5–14px, hard to read — */
.v2-goal-summary {
  font-size: 15px;
  padding: 12px 14px;
  gap: 10px;
}
.v2-goal-summary-label {
  font-family: var(--v2-font-body) !important;
  font-size: 13px !important;
  letter-spacing: 0.6px !important;
  font-weight: 600;
  color: var(--v2-dim);
}
.v2-goal-summary-name {
  font-size: 15px;
  font-weight: 700;
}
.v2-goal-summary-remain {
  font-family: var(--v2-font-body) !important;
  font-size: 13px !important;
  letter-spacing: 0.2px !important;
  color: var(--v2-ink);
  font-weight: 500;
}
.v2-goal-summary-action {
  font-family: var(--v2-font-body) !important;
  font-size: 12px !important;
  letter-spacing: 0.6px !important;
  font-weight: 600;
}
@media (max-width: 720px) {
  .v2-goal-summary { font-size: 14px; }
  .v2-goal-summary-name { font-size: 14px; }
  .v2-goal-summary-remain { font-size: 12.5px !important; }
  .v2-goal-summary-action { font-size: 11.5px !important; }
}

/* — Pace-bar tier labels: were 8.5px tracking-1.2px (illegible) — */
.v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks {
  font-family: var(--v2-font-body) !important;
  font-size: 12px !important;
  letter-spacing: 0.4px !important;
  font-weight: 600;
  margin-top: 10px !important;
}
.v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks span {
  opacity: 0.7;
}
.v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks span.reached {
  opacity: 1;
  color: var(--v2-indigo);
}

/* — Closest milestone (first non-goal row in roadmap):
     Treat the nearest target like an emotional spotlight — a soft mint
     accent on the points-away line, slightly larger name, and a calm
     breathing pulse on the pip. The aim is "you're SO close, keep going,"
     not "look at me," so the pulse is a ripple rather than a steady glow. */

.roadmap-track > .roadmap-row:first-of-type:not(.goal) {
  border-color: rgba(94, 234, 212, 0.30);
  background: linear-gradient(180deg, rgba(94, 234, 212, 0.07), rgba(94, 234, 212, 0.02));
  position: relative;
}

.roadmap-track > .roadmap-row:first-of-type:not(.goal) .roadmap-name {
  font-size: 19px;
}

.roadmap-track > .roadmap-row:first-of-type:not(.goal) .roadmap-detail {
  font-family: var(--v2-font-body) !important;
  font-size: 14px !important;
  letter-spacing: 0.2px !important;
  color: #5eead4;          /* soft mint — fresh, achievable */
  font-weight: 600;
}

.roadmap-track > .roadmap-row:first-of-type:not(.goal) .roadmap-pip {
  border-color: #5eead4 !important;
  color: #5eead4 !important;
  position: relative;
  animation: closestPulse 2.4s var(--v2-ease-out) infinite;
}

/* Ripple-style pulse — radiates outward and fades, repeats every 2.4s.
   Less attention-seeking than a steady glow, more "heartbeat" than "alarm." */
@keyframes closestPulse {
  0% {
    box-shadow:
      0 0 0 2px rgba(0, 0, 0, 0.35),
      0 0 0 0 rgba(94, 234, 212, 0.55);
  }
  60% {
    box-shadow:
      0 0 0 2px rgba(0, 0, 0, 0.35),
      0 0 0 8px rgba(94, 234, 212, 0);
  }
  100% {
    box-shadow:
      0 0 0 2px rgba(0, 0, 0, 0.35),
      0 0 0 0 rgba(94, 234, 212, 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .roadmap-track > .roadmap-row:first-of-type:not(.goal) .roadmap-pip {
    animation: none;
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.35), 0 0 0 4px rgba(94, 234, 212, 0.25);
  }
}

/* — WIN button: drop the green primary treatment so it matches the
     other match buttons. The "+25 PTS / WIN" eyebrow already conveys
     that wins pay the most; a separate color treatment was redundant. */
.v2-match-btn.hero,
.v2-match-btn.hero:hover {
  background: linear-gradient(180deg, rgba(238, 242, 255, 0.025), transparent) !important;
  border: 1px solid var(--v2-border) !important;
  color: var(--v2-ink) !important;
  box-shadow: none !important;
}
.v2-match-btn.hero:hover {
  border-color: rgba(129, 140, 248, 0.40) !important;
  background: rgba(129, 140, 248, 0.05) !important;
}
.v2-match-btn.hero::after {
  background: radial-gradient(circle at 100% 0%, rgba(129, 140, 248, 0.12), transparent 60%) !important;
  opacity: 0 !important;
}
.v2-match-btn.hero:hover::after {
  opacity: 1 !important;
}
.v2-match-btn.hero .v2-match-btn-label,
.v2-match-btn.hero .v2-match-btn-pts {
  color: inherit !important;
  text-shadow: none !important;
}

/* ============================================================
   Rank-card refinements (round 3)
   - Strip the beveled outer circle from the rank glyph; keep a
     calm ambient glow via drop-shadow only.
   - Two-line, right-justified "Progress to / Emerald I" label.
   - More breathing room around the pace bar.
   - Push the seasonal headline-sub line down so it isn't crowded
     against the headline above it (target ~29px breathing space).
   ============================================================ */

/* — Rank glyph: drop the radial-disc background, the 50% border-radius
     "circle frame," and the rotating conic halo ring. Keep a soft
     drop-shadow on the SVG so it still has weight without the bevel. — */
.v2-rank-glyph {
  background: none !important;
  border-radius: 0 !important;
  filter: drop-shadow(0 4px 14px rgba(129, 140, 248, 0.22))
          drop-shadow(0 0 6px rgba(129, 140, 248, 0.12)) !important;
}
.v2-rank-glyph::before,
.v2-rank-glyph::after {
  display: none !important;
  animation: none !important;
}
.v2-rank-glyph > * {
  filter: none !important;
}

/* — Pace title: stack "Progress to" + goal name, right-justified — */
.v2-pace-title-prefix,
.v2-pace-title-goal {
  display: block;
  text-align: right;
  letter-spacing: 0.6px;
}
.v2-pace-title-prefix {
  color: var(--v2-dim);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
}
.v2-pace-title-goal {
  color: var(--v2-ink);
  font-weight: 700;
  font-size: 13px;
  margin-top: 2px;
  text-transform: none;
}
/* The .v2-pace-meta row uses align-items: baseline; reset for the
   two-line title so the column lays out as a stack. */
.v2-pace-meta {
  align-items: end !important;
}
#v2PaceTitle {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.15;
}

/* — Pace bar: more breathing room above and below — */
.v2-rank-progress-card .v2-pace-meta {
  margin-bottom: 18px;
}
.v2-rank-progress-card .v2-pace-bar {
  margin-top: 4px;
}
.v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks {
  margin-top: 14px !important;
}
.v2-rank-progress-card .v2-rank-progress-head {
  margin-bottom: 10px;
}

/* — Seasonal headline-sub line: was crowding under the headline.
     Push it down ~29px so it sits visually centered between the
     headline and the hero-row cards below. — */
.v2-headline-strip {
  padding-top: 4px;
  padding-bottom: 8px;
}
.v2-headline-sub {
  margin-top: 22px !important;
  font-size: 14px;
  line-height: 1.5;
}

/* ============================================================
   POLISH LAYER v8 — Pass 4 · Stripe-grade refinement pass
   Focus: kill text truncation in daily-target rows, fix FAB/dock
   collisions, tighten desktop hierarchy at >=1400px, and add
   restrained micro-interactions that make the page feel alive
   without adding visual noise. Desktop and mobile tuned separately.
   ============================================================ */

/* ---------- 132 · DAILY-TARGET ROWS · no more truncation, ever ----------
   The previous half-width treatment forced `.action` onto a single line
   with ellipsis, which produced "5 First Pla…" at narrow widths. Allow
   the action text to wrap to 2 lines and let the row grow vertically.
   The mode chip now sits at a fixed compact width so the action column
   gets every spare pixel. — */

.v2-hero-row .v2-dt-row,
.v2-dt-row {
  grid-template-columns: minmax(78px, auto) 1fr auto;
  align-items: center;
  gap: 14px;
  min-height: 46px;
}
.v2-dt-row .action {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.v2-dt-row .total {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.v2-dt-row .total .delta {
  display: inline;
  margin-left: 6px;
}

/* ---------- 133 · DAILY-TARGET ROWS · interactive feel ----------
   The rows currently have a hover but nothing else hints at depth.
   Add a left accent rule that lights on hover, tying the row to
   the section's indigo accent system. — */

.v2-dt-row {
  position: relative;
  cursor: default;
  transition:
    background 0.22s var(--v2-ease-out),
    border-color 0.22s var(--v2-ease-out),
    transform 0.18s var(--v2-ease-out),
    box-shadow 0.22s var(--v2-ease-out);
}
.v2-dt-row::before {
  content: "";
  position: absolute;
  left: 0; top: 8%; bottom: 8%;
  width: 2px;
  background: linear-gradient(180deg, var(--v2-indigo), var(--v2-cyan));
  opacity: 0;
  transform: scaleY(0.4);
  transform-origin: center;
  transition: opacity 0.22s var(--v2-ease-out), transform 0.22s var(--v2-ease-emph);
  border-radius: 1px;
  pointer-events: none;
}
.v2-dt-row:hover::before {
  opacity: 0.85;
  transform: scaleY(1);
}
.v2-dt-row:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 18px -10px rgba(129, 140, 248, 0.25);
}

/* ---------- 134 · DAILY-TARGET HERO NUMBER · ambient halo ----------
   The big "27" gradient text already has a drop-shadow, but it sits
   flat against the card. Add a low-opacity radial halo behind it so
   it lifts off the surface like a stat in a broadcast lower-third. — */

.v2-daily-target {
  isolation: isolate;
}
.v2-dt-hero {
  position: relative;
}
.v2-dt-hero::before {
  content: "";
  position: absolute;
  left: -8%; right: 40%;
  top: 50%;
  height: 140%;
  margin-top: -70%;
  background: radial-gradient(
    ellipse 60% 60% at 30% 50%,
    rgba(129, 140, 248, 0.18),
    transparent 70%
  );
  filter: blur(18px);
  z-index: -1;
  pointer-events: none;
  opacity: 0.85;
}
.v2-dt-hero.done::before,
.v2-dt-hero.won::before {
  background: radial-gradient(
    ellipse 60% 60% at 30% 50%,
    rgba(63, 215, 154, 0.20),
    transparent 70%
  );
}

/* ---------- 135 · DAILY-TARGET NUM · smooth value transitions ----------
   When the points-needed-today number changes, fade-flash the hero
   number so the user sees that the value updated. Keeps the eye on
   the most important data point. — */

@keyframes dtNumFlash {
  0%   { filter: drop-shadow(0 6px 22px rgba(129, 140, 248, 0.32)); }
  35%  { filter: drop-shadow(0 6px 28px rgba(129, 140, 248, 0.55)) brightness(1.12); }
  100% { filter: drop-shadow(0 6px 22px rgba(129, 140, 248, 0.32)); }
}
.v2-dt-num {
  animation: dtNumFlash 0.7s var(--v2-ease-out);
  animation-play-state: paused;
}

/* ---------- 136 · PACE BAR · breathing room + smarter ON PACE label ----
   The vertical "ON PACE" tick line (dashed) extends 8px below the
   bar, but at narrow widths it visually overlaps the tier-tick
   labels. Cap the line so it stays inside the bar's visual envelope. */

.v2-pace-bar { padding: 0; }
.v2-pace-bar .pace-marker-line {
  top: -6px;
  bottom: -6px;
}
.v2-pace-bar .pace-marker-label {
  top: -22px;
  font-size: 9.5px;
  letter-spacing: 1.4px;
  padding: 2px 6px;
  background: rgba(11, 16, 32, 0.65);
  border: 1px solid rgba(129, 140, 248, 0.20);
  border-radius: 999px;
  color: var(--v2-ink);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* ---------- 137 · TIER TICKS · readable spacing on every viewport ----
   Force equal column widths and let unreached tiers stay subtle but
   legible. Removes the "BRONZESILVERGOLD..." crush at narrow widths. */

.v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks {
  display: grid !important;
  grid-template-columns: repeat(6, 1fr);
  gap: 4px;
  text-align: center;
  font-size: 11px !important;
  letter-spacing: 0.3px !important;
}
.v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks span {
  text-align: center;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-family: var(--v2-font-body) !important;
}
@media (max-width: 480px) {
  .v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks {
    font-size: 9.5px !important;
    letter-spacing: 0.1px !important;
    gap: 2px;
  }
}

/* ---------- 138 · RANK CARD · stronger tier name typography ----------
   The current rank ("GOLD IV") should be the second-most-important
   data point on the right hero. Bump weight + add letter-spacing so
   the tier name reads clearly even from across the room. — */

.v2-rank-progress-card .v2-rank-name {
  font-size: 38px;
  letter-spacing: 0.025em;
  line-height: 1.05;
  background: linear-gradient(180deg, var(--v2-ink) 0%, #cbd1e8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.v2-rank-progress-card .v2-rank-next {
  font-family: var(--v2-font-mono);
  font-size: 12px;
  letter-spacing: 0.6px;
  color: var(--v2-dim);
  margin-top: 6px;
}

/* ---------- 139 · DESKTOP · hero-row breathing at >=1400px ----------
   Above 1400px the hero row goes side-by-side. The right rank card
   ends up shorter than the daily-target card. Force equal heights so
   the eye reads them as a paired unit, and tune side padding so the
   pace bar has full-bleed room on the right edge. — */

@media (min-width: 1401px) {
  .v2-hero-row {
    align-items: stretch;
  }
  .v2-hero-row > .v2-rank-progress-card {
    justify-content: space-between;
  }
  .v2-hero-row .v2-rank-progress-card .v2-pace-bar {
    margin-top: 6px;
  }
  /* Push the daily-target hero to bottom of card so its huge "27"
     visually rhymes with the rank tier name on the right card. */
  .v2-hero-row .v2-daily-target {
    justify-content: space-between;
  }
}

/* ---------- 140 · POINTS INPUT · richer flash on commit ----------
   The wrap currently flashes a plain border. Add a soft inner glow
   and brighter tinted background so the input change feels confirmed. */

.v2-points-input-wrap.flash {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.10) inset,
    0 0 0 1px var(--v2-cyan),
    0 0 0 4px rgba(34, 211, 238, 0.18),
    0 6px 22px -8px rgba(34, 211, 238, 0.45),
    0 8px 24px -10px rgba(0, 0, 0, 0.6);
  background: linear-gradient(180deg, #0f1830 0%, #0a1024 100%);
  transition:
    box-shadow 0.32s var(--v2-ease-emph),
    background 0.32s var(--v2-ease-out);
}
.v2-points-input-wrap.flash .v2-points-input {
  text-shadow: 0 0 18px rgba(34, 211, 238, 0.45);
}

/* ---------- 141 · GOAL SUMMARY ROW · clearer Change affordance ----------
   The "CHANGE" link is currently a small mono caps label that can
   look like a status pill. Make it look like a proper action chip
   with a subtle indigo wash and an arrow on hover. — */

.v2-goal-summary-action {
  position: relative;
  padding: 4px 10px 4px 10px !important;
  margin-left: auto;
  background: rgba(129, 140, 248, 0.10);
  border: 1px solid rgba(129, 140, 248, 0.20);
  border-radius: 999px;
  color: var(--v2-indigo) !important;
  border-left: 1px solid rgba(129, 140, 248, 0.20) !important;
  transition: background 0.18s var(--v2-ease-out), color 0.18s var(--v2-ease-out), border-color 0.18s var(--v2-ease-out);
}
.v2-goal-summary:hover .v2-goal-summary-action {
  background: rgba(129, 140, 248, 0.18);
  border-color: rgba(129, 140, 248, 0.40);
  color: #fff !important;
}

/* ---------- 142 · MATCH BUTTONS · slightly tighter density ----------
   The 2x2 match grid was eating ~200px of vertical space at the top
   of the cockpit. Bring padding down a touch so the points input is
   visible without scrolling on shorter laptops. — */

@media (min-width: 961px) {
  .v2-match-btn { padding: 12px 14px; }
  .v2-match-btn-pts { font-size: 10.5px; }
  .v2-match-btn-label { font-size: 22px; margin-top: 4px; }
}

/* ---------- 143 · SIDEBAR · sticky tighter top section on tall screens ----
   On tall desktops the sidebar has a lot of empty space below the
   sync row. Keep the sync footer naturally at bottom, and let the
   sections flow with consistent gaps. — */

@media (min-width: 961px) {
  .v2-sidebar { gap: 28px; }
  .v2-sidebar > section + section { padding-top: 26px; }
  .v2-sync { margin-top: auto; }
}

/* ---------- 144 · FAB · stop colliding with rank pace bar ----------
   At 961-1200px the FAB sits at bottom-right (default) and lands
   on top of the right-edge of the rank card pace bar. Shift it
   right-edge inward + raise it so the rank bar stays clear, and add
   the cyan ring micro-pulse from the design system. — */

@media (min-width: 961px) and (max-width: 1240px) {
  /* Shrink FAB into a circular icon on narrow desktop so it claims a
     small, predictable corner instead of crashing into the rank card.
     Mirrors the mobile treatment but kept slightly larger for clickability. */
  #scotty-widget {
    bottom: 24px !important;
    right: 18px !important;
  }
  #scotty-widget #scotty-toggle {
    padding: 0 !important;
    width: 54px !important;
    height: 54px !important;
    border-radius: 50% !important;
    font-size: 0 !important;
    color: transparent !important;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    position: relative;
    box-shadow:
      0 6px 18px -4px rgba(245, 166, 35, 0.55),
      0 0 0 2px rgba(11, 16, 32, 0.9),
      0 0 0 3px rgba(245, 166, 35, 0.50) !important;
  }
  #scotty-widget #scotty-toggle::before {
    content: "";
    width: 24px; height: 24px;
    background-color: #0b1020;
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M4 4h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-5l-4 4v-4H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm3 6h10v2H7v-2Zm0 4h7v2H7v-2Z'/></svg>") center / contain no-repeat;
            mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='black' d='M4 4h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-5l-4 4v-4H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm3 6h10v2H7v-2Zm0 4h7v2H7v-2Z'/></svg>") center / contain no-repeat;
  }
  #scotty-widget #scotty-label { display: none !important; }
  /* Move last-updated pill above FAB so they don't share the corner */
  .last-updated { right: 86px !important; bottom: 30px !important; }
}

/* ---------- 145 · MOBILE · dock contrast + safe-area tuning ----------
   The dock backdrop currently fades from transparent to opaque, but
   in mid-page scroll the buttons can read against bright content.
   Push the backdrop opacity higher and add a faint top inner highlight
   so the button bar feels like a separate surface. — */

@media (max-width: 960px) {
  .v2-quick-dock {
    background:
      linear-gradient(180deg,
        rgba(11, 16, 32, 0.86) 0%,
        rgba(11, 16, 32, 0.96) 30%,
        rgba(11, 16, 32, 0.99) 100%);
    border-top: 1px solid rgba(129, 140, 248, 0.22);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.05),
      0 -16px 36px -16px rgba(0, 0, 0, 0.7);
  }
  /* Increase main bottom padding to clear dock + FAB stack reliably */
  .v2-main { padding-bottom: calc(132px + var(--v2-safe-bottom, 0px)); }
}

/* ---------- 146 · MOBILE · cockpit density on first viewport ----------
   At 375px the cockpit eats nearly the entire first scroll before
   any data card is visible. Tighten section gap and step rule so
   users see the headline + Today's Target above the fold sooner. — */

@media (max-width: 480px) {
  .v2-sidebar { gap: 14px; padding: 14px 14px 16px; }
  .v2-sidebar > section + section { padding-top: 16px; }
  .v2-sidebar > section + section::before { opacity: 0.6; }
  .v2-masthead { padding-bottom: 10px; }
  .v2-masthead-title { font-size: 24px; }
  .v2-section-label { margin-bottom: 8px !important; }
  .v2-mode-tabs { margin-bottom: 8px; }
  .v2-match-grid { gap: 5px; }
  .v2-match-btn { padding: 11px 12px; min-height: 56px; }
  .v2-match-btn-label { font-size: 18px; margin-top: 3px; }
  .v2-match-btn-pts { font-size: 9.5px; }
  .v2-undo { margin-top: 6px; padding: 7px 14px; font-size: 9.5px; }
  .v2-points-input-wrap { /* keep tappable */ }
  .v2-goal-summary { padding: 9px 11px; }
  .v2-sync { padding: 9px 10px; font-size: 10px; }
}

/* ---------- 147 · MOBILE · lift scotty FAB above dock cleanly ----
   The FAB already sits at bottom: 80px on mobile, but the dock height
   has grown with v95/96. Recompute clearance so the FAB and the dock
   never visually touch. — */

@media (max-width: 640px) {
  #scotty-widget {
    bottom: calc(86px + var(--v2-safe-bottom, 0px)) !important;
    right: 14px !important;
  }
}

/* ---------- 148 · DESKTOP · hover sheen on daily-target card ----------
   The card has the underlying layer-24 sheen. Reinforce it with a
   subtle gradient brightening on hover so the section feels alive. */

@media (min-width: 961px) {
  .v2-daily-target {
    transition:
      box-shadow 0.3s var(--v2-ease-out),
      border-color 0.3s var(--v2-ease-out);
  }
  .v2-daily-target:hover {
    border-color: rgba(129, 140, 248, 0.30);
    box-shadow:
      0 1px 0 rgba(255, 255, 255, 0.04) inset,
      0 0 0 1px rgba(129, 140, 248, 0.18),
      0 18px 38px -16px rgba(0, 0, 0, 0.65),
      0 8px 18px -6px rgba(129, 140, 248, 0.18);
  }
}

/* ---------- 149 · BEHIND-PACE chip · clearer warning state ----------
   Currently the chip uses `accent-crimson` color class whose `.behind`
   bg is too quiet. Strengthen contrast so it actually catches the
   user's eye, but keep it warm-orange (not alarming red). */

.v2-headline .accent-crimson {
  color: #ffb88a;
  text-shadow: 0 0 24px rgba(249, 115, 22, 0.35);
}

/* "Behind Pace" status pill that headline-v3 emits — boost it. */
.v2-pace-chip.is-behind {
  color: #ffba90;
  border-color: rgba(249, 115, 22, 0.45);
  background:
    linear-gradient(180deg, rgba(249, 115, 22, 0.18), rgba(249, 115, 22, 0.06));
  box-shadow:
    inset 0 0 12px -2px rgba(249, 115, 22, 0.32),
    0 0 0 1px rgba(249, 115, 22, 0.14);
}

/* ---------- 150 · NAV DRAWER · prevent right-edge bleed at >=1700px ---
   The shared off-canvas nav menu sits at right:-320px when closed.
   `body { overflow-x: clip }` should hide it, but in some Safari/
   Edge builds the parent grid expands. Force a hard right-edge clip
   on the shell so no chrome ever leaks. */

.v2-shell {
  overflow-x: clip;
  contain: paint;
}

/* ---------- 151 · CARD SHADOW · unified depth tier across components ---
   Cards currently use --v2-card-shadow but the daily-target card has
   only a border. Apply the shared shadow so all editorial blocks read
   at the same elevation. */

.v2-daily-target {
  box-shadow: var(--v2-card-shadow);
}
.v2-daily-target:hover {
  box-shadow: var(--v2-card-shadow-hover);
}

/* ---------- 152 · MILESTONES · smoother row chrome ----------
   The roadmap rows are functional but lack the breathing room of the
   daily-target rows. Match their padding + height for cross-card
   visual rhythm. */

.roadmap-row {
  padding: 12px 14px;
  min-height: 48px;
  border-radius: 3px;
}
.roadmap-row.goal {
  border-radius: 3px;
}
.roadmap-name { font-size: 17px; }
.roadmap-detail { letter-spacing: 0.3px; }

/* ---------- 153 · SECTION ENTRANCE · gentler stagger ----------
   The current 0.05–0.48s stagger feels rushed. Bump first delay,
   reduce per-step delta so the page settles smoothly. */

.v2-main > *:nth-child(1) { animation-delay: 0.08s; }
.v2-main > *:nth-child(2) { animation-delay: 0.16s; }
.v2-main > *:nth-child(3) { animation-delay: 0.22s; }
.v2-main > *:nth-child(4) { animation-delay: 0.28s; }
.v2-main > *:nth-child(5) { animation-delay: 0.32s; }
.v2-main > *:nth-child(6) { animation-delay: 0.36s; }
.v2-main > *:nth-child(7) { animation-delay: 0.40s; }
.v2-main > *:nth-child(8) { animation-delay: 0.44s; }

/* ---------- 154 · FOCUS STATE · ensure all cockpit buttons are reachable -
   The :focus-visible ring exists but goal pills + sync action buttons
   need explicit support. */

.v2-sync-action:focus-visible,
.v2-goal-summary:focus-visible,
.v2-goal-other:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--v2-bg),
    0 0 0 4px rgba(129, 140, 248, 0.55),
    0 0 18px -4px var(--v2-indigo-glow);
  border-radius: 3px;
}

/* ---------- 155 · COUNTDOWN PILL · subtle motion on countdown change ---
   The amber "75 DAYS LEFT" pill sits static. Add a slow pulsing brighten
   so it feels live, matching the cyan masthead-sub dot. */

.v2-countdown-pill {
  position: relative;
  overflow: hidden;
}
.v2-countdown-pill::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg,
    transparent 0%,
    rgba(255, 255, 255, 0.45) 50%,
    transparent 100%);
  transform: translateX(-100%);
  animation: countdownSheen 6s var(--v2-ease-out) infinite;
  pointer-events: none;
}
@keyframes countdownSheen {
  0%, 60% { transform: translateX(-100%); }
  80%     { transform: translateX(100%); }
  100%    { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
  .v2-countdown-pill::after { animation: none; display: none; }
}

/* ---------- 156 · LAST-UPDATED PILL · cleaner dot alignment ---------- */

.last-updated::before {
  width: 5px; height: 5px;
}

/* ---------- 157 · MOBILE · headline never blocked by FAB ----------
   At 375–640px the FAB sits at right: 14px, bottom: 86px. The headline
   strip is at top. They never collide in viewport — but at the exact
   scroll where the headline hits FAB level, the gradient text can be
   visually obscured. Add right-side padding so the headline always
   ends at least 60px before the FAB column. */

@media (max-width: 640px) {
  .v2-main { padding-right: 14px; }
  .v2-headline-strip { padding-right: 8px; }
}

/* ---------- 158 · DAILY-TARGET HERO · scale-down at narrow widths ----
   On viewports <420px the "27 PTS LEFT TODAY" line collides with the
   bank line below it. Shrink the unit, keep the number commanding. */

@media (max-width: 420px) {
  .v2-dt-num { font-size: clamp(48px, 13vw, 72px); }
  .v2-dt-unit { font-size: clamp(15px, 4.4vw, 20px); letter-spacing: 0.04em; }
  .v2-dt-bank { font-size: 12.5px; }
  .v2-dt-row { padding: 10px 12px; }
  .v2-dt-row .mode { font-size: 10px; letter-spacing: 1.1px; }
  .v2-dt-row .action { font-size: 13.5px; }
  .v2-dt-row .total { font-size: 13px; }
}

/* ============================================================
   POLISH LAYER v8.1 — desktop layout corrections (Pass 4b)
   - When the anonymous pace-summary card is hidden, the milestones
     card was squeezed to half width and the right side felt empty.
     Make milestones span the full row when its sibling is hidden.
   - Make the rank progress card visually fill its hero-row slot by
     pushing its content with space-between, so the pace bar doesn't
     float in mid-card while the daily-target stretches taller.
   - Wider headline-strip headroom on big desktops.
   ============================================================ */

/* ---------- 159 · PROGRESS ROW · expand when only one child visible ---- */

@media (min-width: 1401px) {
  /* Use modern :has() — when the pace-card is hidden via inline `display:none`,
     allow the roadmap-card to span both columns. */
  .v2-progress-row:has(> .pace-card[style*="display: none"]) {
    grid-template-columns: 1fr;
    max-width: 1080px;
  }
  /* Same when pace-card has no children rendered yet (initial paint) */
  .v2-progress-row:has(> .pace-card:empty) {
    grid-template-columns: 1fr;
    max-width: 1080px;
  }
}

/* Fallback for browsers without :has() — let the roadmap card cap itself
   so the layout doesn't feel unbalanced when the right column is hidden. */
@media (min-width: 1401px) {
  .v2-progress-row > .roadmap-card { max-width: 100%; }
}

/* ---------- 160 · RANK CARD · fill hero-row slot gracefully ----------
   When the daily-target card next to it has 3 path rows + bank line,
   it grows taller than the rank card. Use space-between so the pace
   bar block sits naturally at the bottom of its card. */

@media (min-width: 1401px) {
  .v2-hero-row .v2-rank-progress-card {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 22px;
    min-height: 100%;
  }
  .v2-hero-row .v2-rank-progress-card > .v2-pace-meta {
    margin-top: auto;
  }
}

/* ---------- 161 · MAIN COLUMN · cap content width on 4K monitors ---
   At >=1700px the right column gets ungainly wide and lines run too
   long for comfortable reading. Cap it to a sane max so type + cards
   stay tight. */

@media (min-width: 1700px) {
  .v2-main {
    max-width: 1280px;
  }
}

/* ---------- 162 · UNLOCK ANALYTICS CTA · constrain width on big screens -
   The full-bleed CTA was too dominant at 1440+. Cap it and center.
   Tighten its inner padding so the headline lock-up stays tight. */

@media (min-width: 1101px) {
  .charts-teaser {
    max-width: 920px;
    margin-left: auto;
    margin-right: auto;
    padding: 30px 32px;
  }
}

/* ---------- 163 · SIDEBAR · breathing space at top of section list ---
   The masthead was tight against the first section divider. Add a
   touch more headroom so the cockpit reads as a deliberate stack. */

@media (min-width: 961px) {
  .v2-masthead { padding-bottom: 18px; }
  .v2-sidebar > section + section { padding-top: 28px; }
}

/* ---------- 164 · DAILY-TARGET HERO BACKDROP · scoped to card only ---
   The radial halo I added in 134 was bleeding outside the card on
   shorter cards. Constrain it via overflow-clip on the parent so the
   glow stays inside. */

.v2-daily-target {
  overflow: clip;
}

/* ---------- 165 · ROADMAP REACHED-NEAR row · tighten goal accent ---
   Already present at line 6453+, but the closest-row hover state
   should also reflect the row hover lift. */

.roadmap-track > .roadmap-row:first-of-type:not(.goal):hover {
  background: linear-gradient(180deg, rgba(94, 234, 212, 0.10), rgba(94, 234, 212, 0.04));
}

/* ---------- 166 · KNOB LABEL · make on-bar tag readable ---------- */

.v2-pace-bar .knob:hover::before {
  content: attr(data-pts) " PTS";
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-family: var(--v2-font-mono);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.2px;
  color: var(--v2-ink);
  background: rgba(11, 16, 32, 0.95);
  border: 1px solid rgba(129, 140, 248, 0.40);
  border-radius: 3px;
  padding: 4px 8px;
  pointer-events: none;
}

/* ============================================================
   POLISH LAYER v9 — Stripe-grade micro-quality pass
   Focus: surface fidelity, motion choreography, depth, mobile
   tier-tick crush fix (override the hero-row 4-class specificity
   that beat the v8 layer), live-state pulses, completed/active/
   upcoming language on the tier scale, and primary-action weight
   on the mobile dock. Each rule is scoped so the desktop hero
   layout from v7/v8 stays intact.
   ============================================================ */

/* ---------- 167 · TIER TICKS · mobile crush fix (specificity beat)
   The hero-row selector `.v2-hero-row .v2-rank-progress-card
   .v2-pace-bar + .v2-pace-ticks` (4 classes) was overriding v8 at
   mobile because the rank card stays nested in .v2-hero-row even
   when the row visually stacks. Match its specificity here so
   <=480px viewports actually get the smaller, wrappable labels. */

@media (max-width: 480px) {
  .v2-hero-row .v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks {
    display: grid !important;
    grid-template-columns: repeat(6, 1fr) !important;
    gap: 6px !important;
    font-size: 8px !important;
    letter-spacing: 0 !important;
    text-align: center !important;
    margin-top: 14px !important;
  }
  .v2-hero-row .v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks span {
    white-space: nowrap;
    line-height: 1.1;
    overflow: visible;
    transform-origin: center center;
  }
  .v2-hero-row .v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks span::before {
    top: -7px !important;
    width: 3px !important;
    height: 3px !important;
  }
}
/* Safety net: at very narrow widths, scale the whole tick row to fit
   instead of wrapping the longest tier name. */
@media (max-width: 360px) {
  .v2-hero-row .v2-rank-progress-card .v2-pace-bar + .v2-pace-ticks {
    font-size: 7.5px !important;
    gap: 4px !important;
  }
}

/* ---------- 168 · TIER TICKS · earned/active/upcoming language ----
   The tier scale was reading "current is colored, others are dim."
   Stripe-grade: convey progress through state. Reached tiers gain
   a tiny mint dot; current tier gets a stronger weight + amber
   underline glow; upcoming stay neutral with a subtle separator.
   The dot uses ::before so it doesn't affect grid sizing. */

.v2-pace-ticks span {
  position: relative;
  transition: color 220ms ease, opacity 220ms ease;
}
.v2-pace-ticks span.reached {
  color: var(--v2-indigo);
}
.v2-pace-ticks span.reached::before {
  content: "";
  position: absolute;
  top: -6px;
  left: 50%;
  width: 4px;
  height: 4px;
  border-radius: 999px;
  background: rgba(99, 234, 174, 0.85);
  box-shadow: 0 0 8px rgba(99, 234, 174, 0.55);
  transform: translateX(-50%);
}
.v2-pace-ticks span.current,
.v2-pace-ticks span[data-current="true"] {
  color: #fbbf24;
  font-weight: 700;
  text-shadow: 0 0 12px rgba(251, 191, 36, 0.45);
}
@media (prefers-reduced-motion: reduce) {
  .v2-pace-ticks span { transition: none; }
}

/* ---------- 169 · HEADLINE STRIP · prevent orphaned "Sep 15" ----
   At 375px the meta strip ("BEHIND PACE · 61% projected · Finishing
   Sep 15") wraps so "Sep 15" hangs alone. Group "Finishing" + date
   so they wrap as a unit; the dot separator before them collapses
   when isolated. */

.v2-headline-sub {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 10px;
  row-gap: 6px;
}
.v2-headline-sub > * { white-space: nowrap; }
.v2-headline-sub .v2-finishing,
.v2-headline-sub .accent-date,
.v2-headline-sub time {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
}
@media (max-width: 480px) {
  .v2-headline-sub {
    gap: 6px 8px;
    font-size: 13px;
  }
  .v2-headline-sub .v2-sep:last-of-type { display: none; }
}

/* ---------- 170 · HERO "27" NUMBER · depth via inner highlight ----
   The flat blue gradient on the daily-target hero number reads as
   plastic. Add a subtle inner-rim highlight via a layered gradient
   plus a soft drop-shadow on a pseudo-clone. Compositor-friendly
   (transform/opacity-only on hover sheen). */

.v2-daily-target .v2-dt-num {
  background: linear-gradient(
    180deg,
    #93d4ff 0%,
    #5fa7ff 38%,
    #3b82f6 70%,
    #2563eb 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 2px 14px rgba(59, 130, 246, 0.32));
  position: relative;
  isolation: isolate;
}
.v2-daily-target .v2-dt-num::after {
  content: "";
  position: absolute;
  inset: 4% 8% 18% 8%;
  background: radial-gradient(ellipse at 50% 0%, rgba(255,255,255,0.18), transparent 60%);
  pointer-events: none;
  z-index: -1;
  border-radius: 50%;
  filter: blur(6px);
}

/* ---------- 171 · "BEHIND PACE" pill · breathe with urgency ----
   The pill currently sits static when the user is behind. Add a
   slow ambient pulse to telegraph "this matters" without screaming.
   Stops on hover so it doesn't fight the user. Skipped under
   reduced-motion. */

@keyframes v2BehindBreathe {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(249, 115, 22, 0.0),
                inset 0 0 0 1px rgba(249, 115, 22, 0.40);
  }
  50% {
    box-shadow: 0 0 22px 0 rgba(249, 115, 22, 0.25),
                inset 0 0 0 1px rgba(249, 115, 22, 0.65);
  }
}
.v2-headline-sub .accent-crimson,
.v2-pace-pill.is-behind,
[data-pace="behind"] {
  animation: v2BehindBreathe 3.8s ease-in-out infinite;
}
.v2-headline-sub .accent-crimson:hover {
  animation-play-state: paused;
}
@media (prefers-reduced-motion: reduce) {
  .v2-headline-sub .accent-crimson,
  .v2-pace-pill.is-behind,
  [data-pace="behind"] { animation: none; }
}

/* ---------- 172 · "LAST UPDATED" green dot · live pulse ----------
   The green dot is currently solid. Make it feel "live" with a
   gentle ripple — communicates that the tracker is actively
   syncing without getting in the way. */

@keyframes v2LiveRipple {
  0% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.55); }
  70% { box-shadow: 0 0 0 6px rgba(34, 197, 94, 0); }
  100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0); }
}
.v2-last-updated::before,
.v2-last-updated .dot,
.live-dot {
  animation: v2LiveRipple 2.6s ease-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .v2-last-updated::before,
  .v2-last-updated .dot,
  .live-dot { animation: none; }
}

/* ---------- 173 · COCKPIT RESULT TILES · subtle hover sheen -----
   The +25 PTS / WIN tiles in the sidebar are flat at rest. Add a
   barely-there gradient sheen on hover for a "tap me" affordance,
   plus a tighter focus ring for keyboard users. */

.v2-cockpit .v2-result,
.v2-points-tile,
.v2-quick-tile,
.match-tile {
  transition:
    background 220ms ease,
    transform 180ms cubic-bezier(0.16, 1, 0.3, 1),
    border-color 220ms ease,
    box-shadow 220ms ease;
}
.v2-cockpit .v2-result:hover,
.v2-points-tile:hover,
.v2-quick-tile:hover,
.match-tile:hover {
  transform: translateY(-1px);
  border-color: rgba(129, 140, 248, 0.40);
  background:
    linear-gradient(180deg, rgba(129, 140, 248, 0.08), rgba(129, 140, 248, 0.02)),
    rgba(15, 22, 41, 0.55);
  box-shadow:
    0 6px 18px -10px rgba(99, 102, 241, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.v2-cockpit .v2-result:focus-visible,
.v2-points-tile:focus-visible,
.v2-quick-tile:focus-visible,
.match-tile:focus-visible {
  outline: 2px solid rgba(129, 140, 248, 0.7);
  outline-offset: 2px;
}

/* ---------- 174 · MOBILE DOCK · primary action weight bump ------
   At <=720, the bottom dock has 4 buttons (WIN / LOSE / R2 KO /
   undo). WIN is the most-likely tap so it should read first.
   Push a slight scale and stronger surface on the +WIN tile. */

@media (max-width: 720px) {
  .v2-quick-dock .quick-action[data-mode="WIN"],
  .v2-quick-dock .dock-btn--win,
  .v2-quick-dock > :first-child {
    background:
      linear-gradient(180deg, rgba(34, 197, 94, 0.20), rgba(22, 163, 74, 0.12)),
      rgba(8, 14, 28, 0.85);
    border-color: rgba(34, 197, 94, 0.55);
    box-shadow:
      0 8px 22px -12px rgba(34, 197, 94, 0.55),
      inset 0 1px 0 rgba(255, 255, 255, 0.06);
  }
  .v2-quick-dock .quick-action[data-mode="WIN"]:active,
  .v2-quick-dock > :first-child:active {
    transform: translateY(1px) scale(0.99);
  }
  .v2-quick-dock {
    backdrop-filter: blur(14px) saturate(1.1);
    -webkit-backdrop-filter: blur(14px) saturate(1.1);
    background: linear-gradient(180deg, rgba(8, 12, 24, 0.78), rgba(8, 12, 24, 0.94));
    border-top: 1px solid rgba(255, 255, 255, 0.06);
  }
}

/* ---------- 175 · GOAL BADGE · emerald-tinted "EMERALD I" -------
   When the user's goal is Emerald, the badge in the sidebar reads
   in generic indigo. Tint it specifically — the tier scale already
   uses emerald in the rank ladder, this just keeps the color story
   consistent across the page. */

.v2-goal-summary [data-tier="EMERALD"],
.v2-goal-summary .tier-emerald,
.goal-badge--emerald {
  background:
    linear-gradient(180deg, rgba(16, 185, 129, 0.18), rgba(5, 150, 105, 0.06));
  border-color: rgba(16, 185, 129, 0.55);
  color: #6ee7b7;
  text-shadow: 0 0 10px rgba(16, 185, 129, 0.35);
}

/* ---------- 176 · "11 MORE RANKS" pill · clearer affordance -----
   The collapsed-rows toggle was a thin pill with low contrast.
   Bump padding + add a chevron-only motion on hover. */

.roadmap-track .roadmap-toggle,
.v2-rank-progress-card .roadmap-more,
.expand-rest {
  padding: 8px 18px;
  border-radius: 999px;
  border: 1px solid rgba(129, 140, 248, 0.30);
  background: rgba(15, 22, 41, 0.60);
  font-family: var(--v2-font-mono);
  font-size: 12px;
  letter-spacing: 1.2px;
  transition: background 220ms ease, border-color 220ms ease, transform 180ms ease;
}
.roadmap-track .roadmap-toggle:hover,
.v2-rank-progress-card .roadmap-more:hover,
.expand-rest:hover {
  background: rgba(99, 102, 241, 0.14);
  border-color: rgba(129, 140, 248, 0.55);
  transform: translateY(-1px);
}

/* ---------- 177 · TABULAR NUMS · stable widths everywhere -------
   Numeric displays should use tabular-nums so digits don't shift
   width when a value changes (440 → 465 was visibly jumping). */

.v2-headline,
.v2-headline-sub,
.v2-dt-num,
.v2-points-input,
.v2-rank-progress-card,
.v2-pace-ticks,
.v2-result .pts,
.v2-result .points,
.v2-quick-dock,
.dock-btn,
.match-tile,
[data-numeric="true"] {
  font-variant-numeric: tabular-nums;
}

/* ---------- 178 · KEYBOARD FOCUS · unified ring across CTAs -----
   Apply a consistent focus ring to all interactive surfaces that
   currently rely on default user-agent outlines (which were getting
   eaten by container backgrounds). */

.v2-shell button:focus-visible,
.v2-shell a:focus-visible,
.v2-shell [role="button"]:focus-visible,
.v2-shell input:focus-visible,
.v2-shell select:focus-visible,
.v2-shell [tabindex]:focus-visible {
  outline: 2px solid rgba(99, 102, 241, 0.75);
  outline-offset: 2px;
  border-radius: inherit;
}

/* ---------- 179 · DESKTOP HEADLINE · tighter character on hero --
   At >=1240 the headline characters were a touch loose. Tighten
   for editorial weight without affecting readability. */

@media (min-width: 1240px) {
  .v2-headline {
    letter-spacing: -0.005em;
  }
  .v2-headline strong,
  .v2-headline .accent-pace,
  .v2-headline .accent-amber,
  .v2-headline .accent-date {
    letter-spacing: -0.01em;
  }
}

/* ---------- 180 · CHANGE PILL · bigger tap target on mobile -----
   The "CHANGE" pill in the goal summary was 24px tall — below the
   44px touch target Apple recommends. Bump on small screens. */

@media (max-width: 720px) {
  .v2-goal-summary .change-goal,
  .v2-goal-summary .v2-pill,
  .goal-change-btn {
    min-height: 36px;
    padding: 8px 14px;
    font-size: 12px;
  }
}

/* ---------- 181 · DAILY-TARGET ROW POINTS · numeric tabular -----
   The "+27 pts" / "+28 pts" / "+30 pts" column wasn't aligned
   because each line had its own kerning. Tabular + right-align
   gives a clean stack. */

.v2-daily-target .v2-dt-row .total,
.v2-dt-row .total {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ---------- 182 · CTA CARD GLOW · cap at 1240+ for big screens --
   The "Unlock Performance Analytics" banner gradient was extending
   to full width on 4K. Already capped at 920px in v8. Now also
   add a cleaner edge fade so the chart-line illustration doesn't
   look chopped against the rounded container. */

.v2-shell .unlock-cta::after,
.v2-shell [data-cta="unlock"]::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background:
    linear-gradient(90deg, transparent 0%, transparent 80%, rgba(8, 12, 28, 0.85) 100%);
  pointer-events: none;
}

/* ---------- 183 · SIDEBAR LIVE BADGE · sync with last-updated ---
   The "SEASON 10 · LIVE" line in the sidebar masthead has a green
   dot. Pulse it the same way as the last-updated ribbon so the
   "live system" cue is consistent across both. */

.v2-masthead .v2-live-dot,
.v2-masthead .live-dot,
.v2-masthead [data-live="true"]::before {
  animation: v2LiveRipple 2.6s ease-out infinite;
}

/* ---------- 184 · COUNTDOWN PILL · slight typographic punch -----
   "75 DAYS LEFT" reads as utility text. Bump weight + a soft
   amber glow when the deadline is <30 days away. */

.v2-countdown,
.v2-days-left,
.v2-masthead .v2-deadline {
  font-weight: 700;
  letter-spacing: 0.6px;
}
.v2-countdown[data-urgent="true"],
.v2-days-left.is-soon {
  color: #fbbf24;
  text-shadow: 0 0 14px rgba(251, 191, 36, 0.40);
}

/* ---------- 185 · POINTS INPUT · smoother increment animation ---
   Tapping +/- on the points input was jumping the digit visually.
   A short transition on the digit value makes the change feel
   intentional rather than a yanked replacement. */

.v2-points-display,
.v2-points-input .value,
[data-role="points-value"] {
  transition: color 200ms ease, transform 200ms ease;
}
.v2-points-display.bumped,
.v2-points-input.is-changing .value {
  transform: scale(1.04);
}

/* ---------- 186 · CARD HOVER · unified shadow elevation system --
   Cards across the page used 4 different shadow signatures.
   Standardize on one elevation curve so depth reads consistently. */

.v2-shell .v2-card {
  transition: box-shadow 280ms ease, border-color 280ms ease, transform 220ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .v2-shell .v2-card:hover {
    border-color: rgba(129, 140, 248, 0.30);
    box-shadow:
      0 24px 60px -30px rgba(0, 0, 0, 0.65),
      0 8px 18px -10px rgba(99, 102, 241, 0.20),
      inset 0 1px 0 rgba(255, 255, 255, 0.04);
  }
}

/* ============================================================
   POLISH LAYER v13 — strategic reorder + Stripe-grade refinement
   Focus: mobile content priority, desktop rhythm, hierarchy of
   the "answer-first" hero card, CTA elevation, share-frame fit.
   ============================================================ */

/* ---------- 187 · MOBILE · main-first content order ----------
   The cockpit (sidebar) currently renders BEFORE the headline +
   hero on mobile, forcing returning users to scroll past all
   input UI before seeing their pace answer. Flip the visual
   order so editorial content reads first; the cockpit becomes
   a "tools below" panel. The fixed bottom quick-log dock keeps
   logging within thumb-reach regardless of scroll position. */

@media (max-width: 960px) {
  .v2-main { order: 1; }
  .v2-sidebar {
    order: 2;
    /* Was bordered on the bottom (when stacked, cockpit-first).
       Now that it sits below the editorial flow, draw the divider
       on top so the cockpit reads as a separate panel. */
    border-bottom: none;
    border-top: 1px solid var(--v2-border);
  }
}

/* ---------- 188 · MOBILE · cockpit framing -------------------
   Tighten the cockpit's masthead now that it follows the
   editorial flow. The big "WORLD TOUR" wordmark is no longer
   doing the work of a page heading — drop it half a step so
   the LOG MATCH eyebrow reads as the section's purpose. */

@media (max-width: 960px) {
  .v2-sidebar { gap: 24px; }
  .v2-sidebar > section + section { padding-top: 24px; }
  .v2-masthead-title {
    font-size: 22px;
    letter-spacing: 0.04em;
  }
  .v2-masthead-sub {
    font-size: 10.5px;
    letter-spacing: 1.6px;
  }
}

/* ---------- 189 · MOBILE · share-frame fit-to-container ------
   The 500×300 share-card frame overflows narrow viewports
   (390px wide leaves 110px clipped). Scale the preview down
   proportionally so the artifact sits centered and intact,
   while the underlying export still renders at native 1000×600. */

@media (max-width: 720px) {
  .v2-share-card-row {
    justify-content: center;
  }
  .v2-share-frame {
    width: 100%;
    max-width: 500px;
    height: auto;
    aspect-ratio: 1000 / 600;
  }
  .v2-share-card {
    /* Stay in the top-left of the frame and scale to fill it.
       transform-origin already top-left from base styles. */
    transform: scale(calc(min(100vw - 80px, 500px) / 1000));
  }
}

@media (max-width: 480px) {
  .v2-share-card-shell {
    padding: 16px;
    gap: 12px;
  }
  .v2-share-actions {
    flex-direction: column;
    align-items: stretch;
  }
  .v2-share-btn {
    width: 100%;
    padding: 14px 18px;
  }
}

/* ---------- 190 · DESKTOP · headline strip · breathable rhythm
   The headline + sub-meta line had inconsistent vertical air on
   wide screens. Add a deliberate cadence so the eye lands on the
   answer ("31 PTS/DAY"), then naturally drifts to the meta chips. */

@media (min-width: 961px) {
  .v2-headline-strip {
    padding: 8px 0 4px;
  }
  .v2-headline-sub {
    margin-top: 14px;
    line-height: 1.6;
  }
}

/* ---------- 191 · DAILY-TARGET · primary card pedestal -------
   The daily-target card carries the most-asked question on the
   page ("Can I stop playing yet?"). On wide screens where it
   shares the row with the rank card, lift it half a step so its
   primacy reads at a glance. Subtle — not alarming. */

@media (min-width: 1401px) and (hover: hover) and (pointer: fine) {
  .v2-hero-row > .v2-daily-target {
    box-shadow:
      0 1px 0 rgba(255, 255, 255, 0.06) inset,
      0 0 0 1px rgba(129, 140, 248, 0.20),
      0 22px 50px -22px rgba(0, 0, 0, 0.7),
      0 8px 20px -10px rgba(99, 102, 241, 0.20);
  }
  .v2-hero-row > .v2-daily-target:hover {
    box-shadow:
      0 1px 0 rgba(255, 255, 255, 0.08) inset,
      0 0 0 1px rgba(129, 140, 248, 0.32),
      0 28px 56px -22px rgba(0, 0, 0, 0.75),
      0 12px 24px -10px rgba(99, 102, 241, 0.28);
  }
}

/* ---------- 192 · CARD RADIUS · consistency lock -------------
   Some primary cards used 3px, others 4px, others inherited 0.
   Lock a single radius for the editorial column's primary
   surfaces so the page reads as one design system. */

.v2-daily-target,
.v2-rank-progress-card,
.roadmap-card,
.pace-card,
.charts-teaser,
.chart-card,
.v2-share-card-shell,
.v2-share-frame {
  border-radius: 6px;
}

/* ---------- 193 · ROADMAP GOAL ROW · destination affordance --
   The "goal" row in Next Milestones marks where the user is
   heading. Crisp the border + add a soft outer halo so it
   reads as the destination, not just another list item. */

.roadmap-row.goal {
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.06) inset,
    0 0 0 1px rgba(129, 140, 248, 0.40),
    0 16px 36px -18px rgba(99, 102, 241, 0.40);
}

/* ---------- 194 · CTA TEASER · elevation + interactive hint --
   The "Unlock Performance Analytics" card was visually flat
   relative to the data-rich cards above it. Add a defined
   border + soft elevation so it reads as a clickable
   destination. Tighten the Discord button hover. */

.charts-teaser {
  border: 1px solid rgba(129, 140, 248, 0.18);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    0 0 0 1px rgba(129, 140, 248, 0.08),
    0 22px 48px -22px rgba(0, 0, 0, 0.65),
    0 8px 18px -10px rgba(99, 102, 241, 0.18);
}
.charts-teaser .discord-btn {
  transition: transform 0.18s var(--v2-ease-out),
              box-shadow 0.22s var(--v2-ease-out),
              filter 0.18s var(--v2-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .charts-teaser .discord-btn:hover {
    transform: translateY(-1px);
    filter: brightness(1.06);
  }
}
.charts-teaser .discord-btn:active {
  transform: translateY(0);
}

/* ---------- 195 · DAILY-TARGET ROW · tactile press state -----
   The .v2-dt-row already has a hover state but no press feedback.
   Add a subtle transform so taps feel responsive on touch. */

.v2-dt-row {
  transition: background 0.18s var(--v2-ease-out),
              border-color 0.18s var(--v2-ease-out),
              transform 0.08s var(--v2-ease-out);
}
.v2-dt-row:active {
  transform: scale(0.995);
}

/* ---------- 196 · PACE BAR · soft inner sheen ----------------
   The pace-bar fill already has a top-edge highlight; add a
   complementary top-of-track highlight so the bar reads as a
   recessed channel rather than a flat block. */

.v2-pace-bar::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.05) 0%,
    transparent 35%);
  border-radius: inherit;
}

/* ---------- 197 · SECTION LABEL · consistent eyebrow rhythm --
   Some "− CURRENT POINTS" / "− NEXT MILESTONES" labels used
   slightly different letter-spacing. Lock the editorial eyebrow
   so all section labels feel cut from the same broadcast bar. */

.v2-section-label {
  font-feature-settings: "tnum" 1, "case" 1;
}

/* ---------- 198 · IN-PAGE SMOOTH SCROLL ---------------------
   The "Started the season late?" toggle reveals content;
   smooth in-page motion when other sections expand. */

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* ---------- 199 · FOOTER · subdued contrast restoration -----
   The footer's amber link color contrasted strongly against the
   indigo/cyan palette. Pull it into the family with indigo, with
   amber reserved for the brand mark above. */

.page-footer a {
  color: var(--v2-indigo);
  transition: color 0.18s var(--v2-ease-out);
}
.page-footer a:hover {
  color: var(--v2-cyan);
}
.footer-links a.feedback {
  color: var(--v2-cyan);
}
.footer-links a.feedback:hover {
  color: var(--v2-ink);
}

/* ---------- 200 · ASK SCOTTY FAB · stay above quick-dock -----
   On mobile the Scotty FAB and the bottom quick-dock can stack
   awkwardly. Existing rule lifts the FAB; reinforce the offset
   so the bubble never overlaps the WIN button at narrow widths. */

@media (max-width: 480px) {
  #scotty-widget {
    bottom: calc(86px + var(--v2-safe-bottom, 0px)) !important;
  }
}

/* ---------- 210 · LEGACY ESCAPE-HATCH LINK ----------
   Anchored to the viewport's upper-right, just below the 54px shared navbar.
   Intentionally low-key: it's an opt-out, not a feature. Hover lifts the
   surface with the same indigo glow used by the cockpit cards. */
.v2-legacy-link {
  position: fixed;
  top: calc(54px + 12px);
  right: 16px;
  z-index: 90; /* below navbar (typically 100+), above page chrome */
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 12px;
  font-family: inherit;
  font-size: 12px;
  line-height: 1;
  letter-spacing: 0.2px;
  color: var(--v2-dim);
  text-decoration: none;
  background: rgba(15, 17, 26, 0.72);
  border: 1px solid var(--v2-border, rgba(255, 255, 255, 0.08));
  border-radius: 999px;
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  transition:
    color 160ms ease,
    border-color 160ms ease,
    background-color 160ms ease,
    transform 160ms ease,
    box-shadow 160ms ease;
}

.v2-legacy-link:hover,
.v2-legacy-link:focus-visible {
  color: var(--v2-ink);
  border-color: var(--v2-indigo);
  background: rgba(99, 102, 241, 0.12);
  box-shadow: 0 6px 20px var(--v2-indigo-glow);
  transform: translateY(-1px);
  outline: none;
}

.v2-legacy-link__icon {
  font-size: 13px;
  transition: transform 160ms ease;
}

.v2-legacy-link:hover .v2-legacy-link__icon {
  transform: translateX(-2px);
}

@media (max-width: 720px) {
  /* Drop the label on narrow screens — keep just the arrow chip so it
     never collides with the masthead title or the countdown pill. */
  .v2-legacy-link {
    padding: 6px 9px;
    font-size: 11px;
  }
  .v2-legacy-link__label {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .v2-legacy-link,
  .v2-legacy-link__icon {
    transition: none;
  }
  .v2-legacy-link:hover {
    transform: none;
  }
}



/* ============================================================
   18 · EMPTY STATE — main panel collapses to just the headline
   until the user has signal (0 pts AND 0 entries).
   Toggled by tracker.js: body.v2-empty
   ============================================================ */

body.v2-empty .v2-hero-row,
body.v2-empty .v2-progress-row,
body.v2-empty .v2-share-section,
body.v2-empty .charts-teaser,
body.v2-empty #chartsSection,
body.v2-empty .v2-headline-sub {
  display: none !important;
}

body.v2-empty .v2-headline-strip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 22px;
  min-height: 220px;
}

body.v2-empty .v2-headline-strip::after {
  content: "Use the cockpit on the left to log your first match.";
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid rgba(129, 140, 248, 0.28);
  border-radius: 4px;
  background: linear-gradient(180deg, rgba(129, 140, 248, 0.10), rgba(129, 140, 248, 0.04));
  color: var(--v2-ink);
  font-family: var(--v2-font-mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 600;
}

@media (max-width: 960px) {
  body.v2-empty .v2-headline-strip::after {
    content: "Tap a button in the dock below to log your first match.";
  }
}

body:not(.v2-empty) .v2-hero-row,
body:not(.v2-empty) .v2-progress-row {
  animation: v2EmptyToLive 0.32s var(--v2-ease-out) both;
}

@keyframes v2EmptyToLive {
  0%   { opacity: 0; transform: translateY(6px); }
  100% { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  body:not(.v2-empty) .v2-hero-row,
  body:not(.v2-empty) .v2-progress-row {
    animation: none;
  }
}

/* ============================================================
   19 · MOBILE DOCK — 4-button mode-aware quick-log
   Hides duplicate in-flow match grids on ≤960px so the dock is
   the single source of truth for logging. Manual mode keeps its
   in-flow numeric input (the dock can’t host that UI).
   ============================================================ */

@media (max-width: 960px) {
  #cashoutButtons,
  #quickplayButtons,
  #quickCashButtons {
    display: none !important;
  }

  .v2-match-section > .v2-undo {
    display: none !important;
  }

  body[data-match-mode="manual"] .v2-match-section > .v2-undo {
    display: flex !important;
  }

  .v2-quick-dock {
    display: flex !important;
    grid-template-columns: none !important;
    gap: 5px !important;
    padding: 8px 8px calc(8px + var(--v2-safe-bottom, 0px)) !important;
  }
  .v2-quick-dock .qd-btn { flex: 1 1 0; min-width: 0; }

  .v2-quick-dock .qd-btn {
    padding: 9px 4px !important;
    min-height: 52px;
  }
  .v2-quick-dock .qd-btn .pts { font-size: 9.5px; letter-spacing: 0.8px; }
  .v2-quick-dock .qd-btn .lbl { font-size: 13px; }

  .v2-quick-dock .qd-btn[hidden] { display: none !important; }
}

@media (max-width: 380px) {
  .v2-quick-dock .qd-btn .lbl { font-size: 12px; }
  .v2-quick-dock .qd-btn .pts { font-size: 9px; }
}
