:root {
  --ink: #14163B;
  --ink-light: #1E2150;
  --primary: #7C3AED;
  --primary-light: #A78BFA;
  --primary-dark: #5B21B6;
  --pink: #EC4899;
  --orange: #F97316;
  --green: #22C55E;
  --blue: #3B82F6;
  --teal: #14B8A6;
  --gold: #F5A524;
  --bg: #F5F5FB;
  --card: #FFFFFF;
  --text: #1E2140;
  --muted: #80849F;
  --border: #ECEDF7;
  --good: #22C55E;
  --bad: #E8483A;
  --shadow-sm: 0 2px 8px rgba(20,22,59,0.06);
  --shadow-md: 0 10px 28px rgba(20,22,59,0.10);
  --radius-lg: 22px;
  --radius-md: 16px;
  --radius-sm: 10px;
  --sidebar-w: 240px;
  --bottombar-h: 66px;
}

* { box-sizing: border-box; }
html {
  overflow-x: hidden;
  overflow-y: scroll;
  scrollbar-gutter: stable;
}
html, body {
  margin: 0;
  width: 100%;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--primary); text-decoration: none; }

/* ─── App shell / layout ─────────────────────────────────────────────── */
body.guest { display: flex; min-height: 100vh; align-items: flex-start; justify-content: center; }

aside.sidebar {
  width: var(--sidebar-w);
  background: var(--ink);
  padding: 22px 16px;
  display: flex;
  flex-direction: column;
  position: fixed;
  top: 0; left: 0;
  height: 100vh;
  z-index: 20;
}
.sidebar-brand { display: flex; align-items: center; gap: 8px; padding: 4px 8px 24px; font-weight: 800; font-size: 16.5px; color: #fff; line-height: 1.15; }
.sidebar-brand .brand-accent { color: var(--pink); }
.sidebar-nav { display: flex; flex-direction: column; gap: 3px; flex: 1; }
.sidebar-link {
  display: flex; align-items: center; gap: 12px; padding: 11px 14px; border-radius: 999px;
  color: rgba(255,255,255,0.62); font-size: 14.5px; font-weight: 600; transition: background .15s, color .15s;
}
.sidebar-link svg { width: 19px; height: 19px; flex: 0 0 auto; }
.sidebar-link:hover { background: rgba(255,255,255,0.06); color: #fff; }
.sidebar-link.active { background: var(--primary); color: #fff; box-shadow: 0 6px 16px rgba(124,58,237,0.35); }
.sidebar-streak {
  display: flex; align-items: center; gap: 10px; background: rgba(255,255,255,0.06);
  border-radius: var(--radius-md); padding: 12px; margin: 10px 0;
}
.sidebar-streak .flame { font-size: 20px; }
.sidebar-streak-num { color: #fff; font-weight: 800; font-size: 16px; }
.sidebar-streak-label { color: rgba(255,255,255,0.55); font-size: 11px; }
.sidebar-user {
  display: flex; align-items: center; gap: 10px; padding: 12px 10px;
  border-top: 1px solid rgba(255,255,255,0.08); margin-top: 4px;
}
.avatar-circle {
  width: 36px; height: 36px; border-radius: 50%;
  background: linear-gradient(135deg, var(--primary-light), var(--primary));
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 14px; flex: 0 0 auto;
}
.avatar-circle.lg { width: 56px; height: 56px; font-size: 20px; }
.avatar-circle.xl { width: 84px; height: 84px; font-size: 30px; }
.sidebar-user-info { flex: 1; min-width: 0; }
.sidebar-user-name { font-size: 13.5px; font-weight: 700; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-user-role { font-size: 11.5px; color: rgba(255,255,255,0.5); }
.sidebar-logout { color: #FCA5A5; font-size: 12.5px; font-weight: 700; }

header.mobile-topbar {
  display: none; align-items: center; justify-content: space-between;
  /* Home Screen ("Add to Home Screen") mode draws the app full-screen behind
     the notch/Dynamic Island (viewport-fit=cover + a translucent status bar
     is what gives the app its native full-screen look) - without this,
     Safari-in-a-browser-tab looks fine (it reserves that space itself) but
     the standalone home-screen app doesn't, and the menu button/avatar end
     up rendered underneath the notch. env(safe-area-inset-top) pushes the
     bar's actual content down below the cutout while the dark background
     still extends all the way to the true top of the screen. */
  padding: calc(12px + env(safe-area-inset-top)) 16px 12px;
  background: var(--ink); position: sticky; top: 0; z-index: 30;
}
.mobile-topbar-brand { display: flex; align-items: center; gap: 7px; font-weight: 800; font-size: 14.5px; color: #fff; white-space: nowrap; }
.mobile-menu-btn { background: none; border: none; padding: 4px; color: #fff; flex: 0 0 auto; line-height: 0; }
.mobile-menu-btn svg { width: 24px; height: 24px; stroke: #fff; display: block; }

.mobile-menu-sheet { display: none; position: fixed; inset: 0; background: rgba(20,22,59,0.5); z-index: 40; align-items: flex-end; justify-content: center; }
.mobile-menu-sheet.open { display: flex; }
.mobile-menu-card {
  background: var(--card); width: 100%; max-width: 480px; border-radius: 22px 22px 0 0;
  padding: 18px 18px calc(18px + env(safe-area-inset-bottom));
  max-height: 85vh; overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.mobile-menu-card a, .mobile-menu-card button.menu-link {
  display: flex; align-items: center; gap: 12px; padding: 13px 6px; font-size: 15px; font-weight: 600;
  color: var(--text); width: 100%; text-align: left; background: none; border: none;
}
.mobile-menu-card svg { width: 20px; height: 20px; }

nav.bottombar {
  display: none; position: fixed; bottom: 0; left: 0; right: 0; height: var(--bottombar-h);
  background: var(--card); border-top: 1px solid var(--border); box-shadow: 0 -6px 20px rgba(20,22,59,0.08);
  /* Flat 0 here, not env(safe-area-inset-bottom) - on this device that
     value is apparently still non-zero even inside a plain Safari tab
     (Safari's own toolbar already sits below our content and handles the
     home-indicator area itself), so adding it here double-reserved space
     and pushed the bar up with a visible gap above Safari's toolbar. Real
     safe-area clearance is added back in below, scoped to
     (display-mode: standalone) only, where there's no Safari chrome at all
     to have already handled it. */
  z-index: 30; padding-bottom: 0;
}
.bottombar-inner {
  display: flex; height: 66px;
  /* The outer two links (Dashboard, Ring Case) used to sit flush against
     the screen edges with zero horizontal margin, so on a physically
     rounded-corner phone screen the corner curvature clipped part of their
     icon/label. A small minimum gap (plus more via safe-area-inset if the
     device actually reports one, e.g. landscape on a notched iPhone) keeps
     them clear of the curve on every device. */
  padding-left: max(18px, calc(env(safe-area-inset-left) + 10px));
  padding-right: max(18px, calc(env(safe-area-inset-right) + 10px));
}
.bottombar-link { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; color: var(--muted); font-size: 10.5px; font-weight: 600; }
.bottombar-link svg { width: 21px; height: 21px; }
.bottombar-link.active { color: var(--primary); }

main.app-main { min-width: 0; padding: 24px 28px 40px; }
body.authed main.app-main { margin-left: var(--sidebar-w); }
body.guest main.app-main { max-width: 460px; width: 100%; }

@media (max-width: 880px) {
  aside.sidebar { display: none; }
  header.mobile-topbar { display: flex; }
  nav.bottombar { display: block; }
  body.authed main.app-main { margin-left: 0; padding: 16px 14px calc(var(--bottombar-h) + 24px); }
}

/* Home Screen app only (launched standalone, no Safari chrome at all) -
   the bottom nav needs real extra lift above the home-indicator gesture
   bar here, since there's no address bar underneath it absorbing that
   space the way there is in a normal browser tab. Targets BOTH the
   (display-mode: standalone) media feature and the html.pwa-standalone
   class set by the navigator.standalone check in base.html's <head> -
   belt-and-suspenders, since the media feature alone hasn't been
   reliably distinguishing the two contexts on every device tested. */
@media (max-width: 880px) and (display-mode: standalone) {
  nav.bottombar { padding-bottom: calc(env(safe-area-inset-bottom) + 44px); }
  body.authed main.app-main { padding-bottom: calc(var(--bottombar-h) + 68px); }
}
@media (max-width: 880px) {
  html.pwa-standalone nav.bottombar { padding-bottom: calc(env(safe-area-inset-bottom) + 44px); }
  html.pwa-standalone body.authed main.app-main { padding-bottom: calc(var(--bottombar-h) + 68px); }
}

.container { max-width: 1040px; margin: 0 auto; }

/* ─── Cards ───────────────────────────────────────────────────────────── */
.card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 18px; margin-bottom: 16px; box-shadow: var(--shadow-md); }

h2.section-title { font-size: 17px; font-weight: 800; margin: 26px 0 12px; color: var(--text); display: flex; align-items: center; justify-content: space-between; }
h2.section-title:first-child { margin-top: 0; }
h2.section-title .view-all { font-size: 12.5px; font-weight: 700; color: var(--primary); }

.row { display: flex; gap: 10px; flex-wrap: wrap; }
.row > * { flex: 1; min-width: 120px; }

label { display: block; font-size: 12.5px; font-weight: 600; color: var(--muted); margin: 10px 0 5px; }
input[type=text], input[type=email], input[type=password], input[type=number], input[type=date], input[type=time],
select, textarea {
  width: 100%; padding: 11px 13px; border: 1.5px solid var(--border); border-radius: var(--radius-sm);
  font-size: 14.5px; background: #fff; color: var(--text); font-family: inherit;
}
input[type=color] { width: 44px; height: 40px; padding: 3px; border: 1.5px solid var(--border); border-radius: var(--radius-sm); background: #fff; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--primary-light); }
textarea { min-height: 64px; resize: vertical; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 11px 18px;
  border-radius: 999px; border: 1.5px solid var(--border); background: #fff; color: var(--text);
  font-size: 14px; font-weight: 700; cursor: pointer; transition: transform .1s, box-shadow .15s;
}
.btn:active { transform: scale(0.97); }
.btn.accent { background: var(--primary); border-color: var(--primary); color: #fff; box-shadow: 0 6px 16px rgba(124,58,237,0.28); }
.btn.navy { background: var(--ink); border-color: var(--ink); color: #fff; }
.btn.ghost { background: transparent; border-color: transparent; }
.btn.small { padding: 7px 13px; font-size: 12.5px; }
.btn.full { width: 100%; margin-top: 10px; }
.btn.danger { color: var(--bad); border-color: rgba(232,72,58,0.3); background: rgba(232,72,58,0.06); }
.btn:disabled { opacity: .45; cursor: not-allowed; }

.pill { display: inline-block; padding: 4px 11px; border-radius: 999px; font-size: 11px; font-weight: 700; color: #fff; letter-spacing: .01em; }
.hint { color: var(--muted); font-size: 12.5px; display: block; margin-top: 6px; }
.empty { color: var(--muted); font-size: 14px; padding: 12px 2px; }

.list-row { display: flex; justify-content: space-between; align-items: center; padding: 12px 0; border-bottom: 1px solid var(--border); gap: 10px; }
.list-row:last-child { border-bottom: none; }

.flash { background: #F3ECFF; border: 1.5px solid var(--primary); color: #4C1D95; padding: 11px 15px; border-radius: var(--radius-sm); margin-bottom: 14px; font-size: 14px; font-weight: 600; }

/* ─── Athlete switcher (parents with 2+ kids) ─────────────────────────── */
.athlete-switcher { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
.athlete-switcher-label { font-size: 12.5px; color: var(--muted); font-weight: 700; margin-right: 2px; }
.athlete-switcher-pill {
  display: inline-flex; align-items: center; gap: 7px; padding: 5px 12px 5px 5px; border-radius: 999px;
  background: var(--card); border: 1.5px solid var(--border); font-size: 13px; font-weight: 700; color: var(--muted);
}
.athlete-switcher-pill.active { border-color: var(--primary); color: var(--primary); background: #F3ECFF; }

/* ─── Profile header ──────────────────────────────────────────────────── */
.profile-header { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; flex-wrap: wrap; }
.profile-header h1 { margin: 0; font-size: 22px; font-weight: 800; }
.profile-header .sub { color: var(--muted); font-size: 13.5px; margin-top: 2px; }
.profile-header .sub.team-name { font-weight: 600; color: var(--ink); }

/* ─── Icon circle (per-category / per-metric) ────────────────────────── */
.icon-circle { width: 40px; height: 40px; border-radius: 12px; display: flex; align-items: center; justify-content: center; color: #fff; flex: 0 0 auto; font-weight: 800; font-size: 15px; }
.icon-circle.round { border-radius: 50%; }
.icon-circle svg { width: 19px; height: 19px; }

/* ─── Gradient stat tile (used for hero banners) ─────────────────────── */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; margin-bottom: 6px; }
.stat-tile { border-radius: var(--radius-lg); padding: 20px; color: #fff; position: relative; overflow: hidden; box-shadow: var(--shadow-md); }
.stat-tile::after { content: ""; position: absolute; top: -40px; right: -40px; width: 130px; height: 130px; border-radius: 50%; background: rgba(255,255,255,0.14); }
.stat-tile.primary { background: linear-gradient(135deg, var(--primary-light), var(--primary-dark)); }
.stat-tile-label { font-size: 12.5px; font-weight: 700; opacity: .9; position: relative; z-index: 1; }
.stat-tile-value { font-size: 32px; font-weight: 800; margin-top: 4px; position: relative; z-index: 1; }
.stat-tile-sub { font-size: 12px; opacity: .85; margin-top: 2px; position: relative; z-index: 1; }

/* ─── Metric cards ────────────────────────────────────────────────────── */
.metric-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; }
.metric-card { border-radius: var(--radius-lg); }
.metric-card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.metric-card-name { font-size: 13px; font-weight: 700; color: var(--text); }
.metric-card-value { font-size: 26px; font-weight: 800; }
.metric-card-value .unit { font-size: 14px; font-weight: 600; color: var(--muted); margin-left: 3px; }
.metric-card-goal { font-size: 12px; color: var(--muted); margin-top: 2px; }
.metric-delta { font-size: 12px; font-weight: 700; margin-top: 6px; }
.metric-delta.up { color: var(--good); }
.metric-delta.down { color: var(--bad); }

.progress-track { background: var(--bg); border-radius: 999px; height: 8px; overflow: hidden; margin-top: 8px; }
.progress-fill { height: 100%; border-radius: 999px; }
.metric-chart { max-width: 100%; }

/* ─── Training summary ────────────────────────────────────────────────── */
.summary-numbers { display: flex; gap: 28px; margin-bottom: 14px; flex-wrap: wrap; }
.summary-num { font-size: 26px; font-weight: 800; }
.summary-num-label { font-size: 11.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
.cat-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; }
.cat-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.cat-row-name { width: 90px; font-size: 13px; font-weight: 600; flex: 0 0 auto; }
.cat-row-track { flex: 1; background: var(--bg); border-radius: 999px; height: 8px; overflow: hidden; }
.cat-row-fill { height: 100%; border-radius: 999px; }
.cat-row-meta { width: 76px; text-align: right; font-size: 12px; color: var(--muted); flex: 0 0 auto; }

/* ─── Badges ──────────────────────────────────────────────────────────── */
.badge-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: 14px; }
.badge-shield { text-align: center; }
.badge-shield-icon {
  width: 62px; height: 62px; border-radius: 16px; margin: 0 auto 6px; display: flex; align-items: center;
  justify-content: center; font-size: 24px; color: #fff; box-shadow: var(--shadow-sm);
}
.badge-scope-tag {
  display: inline-block; font-size: 10.5px; font-weight: 700; color: var(--muted);
  background: var(--bg); border: 1px solid var(--border); border-radius: 999px;
  padding: 1px 8px; margin-left: 6px;
}
.edit-badge-panel { display: none; padding: 0 0 10px; }
.edit-badge-panel.open { display: block; }

/* ─── Exercise/Drill picker (Build a Workout) ────────────────────────── */
.drill-picker, .athlete-checklist {
  max-height: 260px; overflow-y: auto; border: 1px solid var(--border); border-radius: 12px;
  padding: 4px 10px; margin-top: 6px;
}
.drill-picker-row {
  display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--text);
  padding: 8px 0; border-bottom: 1px solid var(--border);
}
.drill-picker-row:last-child { border-bottom: none; }
.drill-chip-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.drill-chip {
  font-size: 11px; font-weight: 600; color: var(--muted); background: var(--bg);
  border: 1px solid var(--border); border-radius: 999px; padding: 3px 10px;
}

/* ─── Selected exercises/drills list (Add + reorder, replaces the old
   checkbox picker so the same drill can be added more than once and the
   order you build a workout in is preserved) ─────────────────────────── */
.selected-drills {
  max-height: 260px; overflow-y: auto; border: 1px solid var(--border); border-radius: 12px;
  padding: 4px 10px; margin-top: 6px;
}
.selected-drills:empty { display: none; border: none; padding: 0; margin-top: 0; }
.selected-drill-row {
  display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--text);
  padding: 8px 0; border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.selected-drill-row:last-child { border-bottom: none; }
.selected-drill-name { font-weight: 700; }
.selected-drill-actions { display: flex; gap: 4px; margin-left: auto; flex: 0 0 auto; }
.selected-drill-actions .btn.small { padding: 4px 9px; line-height: 1; }

/* ─── Run-workout drill timers ────────────────────────────────────────── */
.drill-timer-row {
  display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.drill-timer-row:last-child { border-bottom: none; }
.drill-timer { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.drill-timer-display { font-size: 14px; font-weight: 800; color: var(--text); min-width: 42px; text-align: center; }

/* ─── Avatar crop modal ───────────────────────────────────────────────── */
.crop-modal-backdrop {
  display: none; position: fixed; inset: 0; background: rgba(20,22,59,0.55);
  z-index: 500; align-items: center; justify-content: center; padding: 20px;
}
.crop-modal-backdrop.open { display: flex; }
.crop-modal-card {
  background: #fff; border-radius: var(--radius-lg); padding: 20px; width: 100%;
  max-width: 420px; box-shadow: var(--shadow-md);
}
.crop-modal-image-wrap { max-height: 60vh; overflow: hidden; background: #111; border-radius: 12px; }
.crop-modal-image-wrap img { display: block; max-width: 100%; }
.crop-modal-actions { display: flex; gap: 10px; margin-top: 14px; justify-content: flex-end; }
.badge-shield.locked { opacity: 0.5; }
.badge-shield.locked .badge-shield-icon { background: #E3E5F2 !important; color: #B7BAD6; filter: none; }
.badge-shield-title { font-size: 11px; font-weight: 700; line-height: 1.25; }
.badge-shield-sub { font-size: 10px; color: var(--muted); margin-top: 1px; }

/* ─── Category / workout rows ────────────────────────────────────────── */
.workout-row { display: flex; align-items: center; gap: 12px; padding: 11px 0; border-bottom: 1px solid var(--border); }
.workout-row:last-child { border-bottom: none; }
.workout-row-date { font-weight: 800; font-size: 12px; color: var(--primary); text-transform: uppercase; letter-spacing: .02em; margin-bottom: 2px; }
.workout-row-title { font-weight: 800; font-size: 14.5px; }
.workout-row-meta { font-size: 12.5px; font-weight: 700; color: var(--muted); margin-top: 1px; }
/* input[type=number] alone (line ~148) sets width:100% and beats a plain
   .drill-minutes-input class on specificity, which is why this box was
   stretching full-width instead of staying small - repeating the attribute
   selector here brings it back up to the same specificity so the override
   actually sticks. */
input[type=number].drill-minutes-input { width: 62px; padding: 5px 6px; border: 1.5px solid var(--border); border-radius: 8px; font-size: 15px; font-weight: 700; font-family: inherit; text-align: center; color: var(--text); }

/* ─── Calendar ────────────────────────────────────────────────────────── */
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; }
.cal-weekday { text-align: center; font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; padding-bottom: 4px; }
.cal-day {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 8px; min-height: 96px; display: flex; flex-direction: column; gap: 4px;
}
.cal-day.other-month { opacity: .4; }
.cal-day.today { border-color: var(--primary); border-width: 2px; }
.cal-day-num { font-size: 12px; font-weight: 700; color: var(--muted); }
.cal-day-weekday { font-size: 10px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }

/* .cal-day-label / .cal-day-body wrap the date bits and the entries/empty
   state respectively. display:contents makes them layout-invisible by
   default so month view renders exactly as before - the week-view rules
   below are the only place that turn them into real flex boxes. */
.cal-day-label, .cal-day-body { display: contents; }
.cal-day-empty { display: none; }

/* Week view (desktop and mobile alike): instead of 7 side-by-side columns,
   stack all 7 days as full-width rows so the whole week is visible with
   normal page scrolling and there's room for a proper icon + name + time
   row per workout. Each row is a date label on the left plus the day's
   workouts (or an empty-state message) on the right. */
.cal-grid-week {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.cal-grid-week .cal-day {
  flex-direction: row;
  align-items: center;
  min-height: auto;
  padding: 14px 16px;
  gap: 14px;
}
.cal-grid-week .cal-day-label {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  flex: 0 0 auto;
  min-width: 44px;
}
.cal-grid-week .cal-day-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}
.cal-grid-week .cal-day-empty {
  display: block;
  color: var(--muted);
  font-size: 13.5px;
}
.cal-entry { border-radius: 8px; padding: 4px 7px; font-size: 10.5px; font-weight: 700; color: #fff; cursor: pointer; }
.cal-entry.scheduled { opacity: .9; }
.cal-entry[data-can-drag="true"], .workout-row[data-can-drag="true"] {
  cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
  /* Anchors are natively draggable by the browser (drag-a-link-out behavior)
     independent of any JS - this turns that native drag off so our custom
     pointer-based drag is the only thing that responds to the gesture. */
  -webkit-user-drag: none; user-drag: none;
  /* On iOS Safari, holding down a link for ~500ms triggers the native
     "callout" menu (Open / Open in New Tab / Copy / Share), which steals
     the touch gesture before our pointer-based drag ever sees it. Same
     idea on Android: suppress the tap-highlight flash so it doesn't look
     like a stuck/ghost press mid-drag. */
  -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent;
}
.dragging { opacity: 0.35; cursor: grabbing; }
.cal-day.drag-over { border-color: var(--primary); background: rgba(124,58,237,0.06); }

/* ─── Goals ───────────────────────────────────────────────────────────── */
/* ─── Goals ───────────────────────────────────────────────────────────── */
.goal-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
.goal-card {
  border-radius: var(--radius-lg); border-top: 4px solid var(--goal-accent, var(--primary));
  /* Cards in the same grid row are stretched to equal height by CSS Grid's
     default align-items:stretch. Making the card itself a flex column and
     pushing .goal-card-actions down with margin-top:auto (rather than just
     letting it trail the content) means the actions row - and the Pin
     button inside it - lands on the same bottom edge across every card in
     a row, regardless of how much goal-specific content sits above it. */
  display: flex; flex-direction: column; position: relative;
}
.goal-card.type-metric { --goal-accent: var(--primary); }
.goal-card.type-count { --goal-accent: var(--blue); }
.goal-card.type-milestone { --goal-accent: var(--gold); }
.goal-card.achieved { background: linear-gradient(180deg, rgba(34,197,94,0.06), var(--card) 40%); }
.goal-card-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.goal-card-head .icon-circle { background: var(--goal-accent, var(--primary)); }
.goal-card-title { font-weight: 800; font-size: 14.5px; flex: 1; min-width: 0; }
.goal-card-type-tag {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  color: var(--goal-accent, var(--primary));
}
.goal-card-value { font-size: 22px; font-weight: 800; margin-bottom: 2px; }
.goal-card-value .unit { font-size: 13px; font-weight: 600; color: var(--muted); margin-left: 3px; }
.goal-card-desc { font-size: 12.5px; color: var(--muted); margin-bottom: 8px; line-height: 1.4; }
.goal-card-date { font-size: 11.5px; color: var(--muted); margin-top: 8px; }
.goal-card-actions { display: flex; align-items: center; gap: 8px; margin-top: auto; padding-top: 10px; flex-wrap: wrap; }
.goal-card-actions-left { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* Dashboard membership is now purely a function of drag position (top
   dashboard_slots cards), not a separate pin/unpin toggle - this badge is
   the only UI communicating "this card is currently featured," and the
   grip handle is what you press-and-drag to change that. */
.dashboard-slot-badge {
  position: absolute; top: -9px; right: 14px;
  background: var(--goal-accent, var(--primary)); color: #fff;
  font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
  padding: 3px 10px; border-radius: 999px; box-shadow: 0 1px 3px rgba(0,0,0,.15);
}
.goal-drag-handle {
  cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
  /* Without these, a press-and-hold on the handle triggers the OS's own
     touch gesture (iOS's callout menu, Android's text-selection/drag-image
     handling) before our pointermove listener ever sees enough movement to
     start the drag - touch-action:none alone stops scrolling but not this.
     Same fix already proven out on the calendar's drag-to-reschedule. */
  -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent;
  -webkit-user-drag: none; user-drag: none;
  color: var(--muted); flex-shrink: 0; padding: 8px; margin: -4px -4px -4px auto; border-radius: 6px;
}
.goal-drag-handle:hover { background: var(--bg); color: var(--text); }
.goal-card.drag-over-before { box-shadow: inset 3px 0 0 var(--primary); }
.goal-card.drag-over-after { box-shadow: inset -3px 0 0 var(--primary); }
.goal-card-empty-slot {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 160px; border: 2px dashed var(--border); background: transparent; box-shadow: none;
  color: var(--muted); font-size: 13px; font-weight: 600; line-height: 1.5;
}
.status-tag.not_started { background: var(--muted); }
.status-tag.in_progress { background: var(--blue); }
.status-tag.done { background: var(--good); }
.edit-goal-panel, .edit-metric-entry-panel { display: none; padding: 10px 0 0; }
.edit-goal-panel.open, .edit-metric-entry-panel.open { display: block; }
.goal-type-tabs { display: flex; gap: 6px; margin-bottom: 14px; }
.goal-type-tab {
  flex: 1; text-align: center; padding: 9px 6px; border-radius: var(--radius-sm); font-size: 12.5px;
  font-weight: 700; color: var(--muted); background: var(--bg); border: 1.5px solid transparent; cursor: pointer;
}
.goal-type-tab.active { color: #fff; border-color: transparent; }
.goal-type-tab[data-type="metric"].active { background: var(--primary); }
.goal-type-tab[data-type="count"].active { background: var(--blue); }
.goal-type-tab[data-type="milestone"].active { background: var(--gold); }
.radio-label {
  display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 600;
  color: var(--text); margin: 4px 0; cursor: pointer;
}
.radio-label input[type="radio"], .radio-label input[type="checkbox"] { margin: 0; accent-color: var(--primary); flex: 0 0 auto; }
.tag-picker-row { display: flex; flex-wrap: wrap; gap: 10px 16px; margin-top: 4px; }
.metric-entry-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.metric-entry-row:last-child { border-bottom: none; }
.metric-entry-row-main { flex: 1; min-width: 0; }
.metric-entry-row-value { font-weight: 800; font-size: 14px; }
.metric-entry-row-meta { font-size: 12px; color: var(--muted); margin-top: 1px; }

table.simple { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.simple th, table.simple td { text-align: left; padding: 7px 4px; border-bottom: 1px solid var(--border); }
table.simple th { color: var(--muted); font-weight: 700; font-size: 11.5px; text-transform: uppercase; letter-spacing: .03em; }

.status-tag { font-size: 10.5px; font-weight: 700; padding: 3px 9px; border-radius: 999px; color: #fff; }
.status-tag.scheduled { background: var(--muted); }
.status-tag.completed { background: var(--good); }

footer.app-footer { text-align: center; color: var(--muted); font-size: 12px; padding: 26px 0 10px; }

.tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
.tabs a { padding: 10px 4px; font-size: 13.5px; font-weight: 700; color: var(--muted); border-bottom: 2px solid transparent; margin-right: 18px; }
.tabs a.active { color: var(--primary); border-color: var(--primary); }

.color-swatch-row { display: flex; gap: 8px; flex-wrap: wrap; margin: 6px 0 10px; }
.color-swatch { width: 26px; height: 26px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; }
.color-swatch.selected { border-color: var(--text); }

/* ─── Ring Case ───────────────────────────────────────────────────────── */
.ring-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 16px; }
.ring-cell { text-align: center; }
.ring-cell-img-wrap {
  width: 84px; height: 84px; margin: 0 auto 8px; display: flex; align-items: center; justify-content: center;
}
.ring-cell-img-wrap img { max-width: 100%; max-height: 100%; filter: drop-shadow(0 2px 4px rgba(0,0,0,.12)); }
.ring-cell.locked .ring-cell-img-wrap img { opacity: 0.9; }
.ring-cell-title { font-size: 12px; font-weight: 800; }
.ring-cell-sub { font-size: 10.5px; color: var(--muted); margin-top: 1px; }
.ring-cell.locked .ring-cell-sub { font-weight: 700; }
.ring-cell-progress { width: 84px; margin: 6px auto 0; }

/* The two Ring Case dashboard cards - one per ladder. Each shows the
   highest ring already earned ("Latest") side by side with the next
   un-earned tier and its progress ("Next"), so the dashboard is both a
   quick brag ("look what you've got") and a nudge ("here's what's next")
   without needing to browse the full Ring Case page. */
.next-ring-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; }
.next-ring-card { display: flex; flex-direction: column; gap: 10px; }
.next-ring-card-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); }
.next-ring-slots { display: flex; align-items: center; gap: 12px; }
.next-ring-slot { flex: 1; min-width: 0; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.next-ring-slot .ring-cell-img-wrap { width: 56px; height: 56px; margin: 0 auto; }
.next-ring-slot-empty {
  width: 56px; height: 56px; border-radius: 50%; border: 2px dashed var(--border);
  display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 10px; font-weight: 700;
}

/* The "Latest" earned ring is the payoff - it gets top billing (bigger
   art) over the "Next" slot, which is mostly progress-bar/text anyway. */
.next-ring-slot.is-latest .ring-cell-img-wrap { width: 104px; height: 104px; }
.next-ring-slot.is-latest .next-ring-slot-empty { width: 104px; height: 104px; font-size: 11px; }
.next-ring-slot.is-latest .next-ring-slot-title { font-size: 13.5px; }
.next-ring-slot-kicker { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); }
.next-ring-slot-title { font-size: 12px; font-weight: 800; line-height: 1.25; }
.next-ring-slot-progress { width: 100%; }
.next-ring-divider { width: 1px; background: var(--border); flex: 0 0 auto; }
