/* ============================================================
   JFIVE THEME — token override layer for index.html
   ------------------------------------------------------------
   Add ONE line in <head>, AFTER the closing </style>:

       <link rel="stylesheet" href="jfive-theme.css">

   Revert by deleting that line.

   This file changes VALUES only — colors and type. It adds no
   ids, renames no classes, alters no markup, contains no JS.
   Your spacing, radius, elevation and semantic scales are
   untouched, so nothing reflows.
   ============================================================ */

@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');

/* ---------- 1. BRAND ---------------------------------------
   --red carried two jobs: brand and danger. You already split
   --danger out, so retinting --red moves only brand surfaces.
   #4F46E5 is 6.31:1 on white — above the 4.5:1 AA minimum,
   where #D0242A sat at 5.12:1. No contrast is lost.
   ----------------------------------------------------------- */
:root {
  --red:       #4F46E5;
  --red-dark:  #4338CA;
  --red-glow:  rgba(79,70,229,0.08);

  /* Secondary accent — AI surfaces only, so "the AI did this"
     is legible at a glance without inventing a sixth status color. */
  --j5-accent:      #7C4DFF;
  --j5-accent-tint: #F4F0FF;

  /* Sidebar/nav shell. Dark chrome + light canvas is the single
     biggest "this costs money" cue, and it costs one variable. */
  --j5-shell:        #0B1330;
  --j5-shell-text:   #A6ADC9;
  --j5-shell-active: rgba(124,77,255,0.20);
}

/* ---------- 2. TYPE ----------------------------------------
   Plus Jakarta Sans replaces Inter at the same metrics, so line
   counts and column widths do not move. Space Grotesk stays on
   metrics and titles. Bebas Neue is retired from the two places
   it still appeared — it reads local-gym, not platform.
   ----------------------------------------------------------- */
body,
.tbl,
.s-label,
.rtag {
  font-family: 'Plus Jakarta Sans', sans-serif;
}

.sb-logo {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--text);
}

.grind-lbl {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--red);
}

/* ---------- 3. SIDEBAR -------------------------------------
   The one structural-looking change, done entirely with color:
   the rail goes dark. No width, padding or position is touched.
   ----------------------------------------------------------- */
.sidebar {
  background: var(--j5-shell);
  border-right: none;
}

.sb-header,
.sb-footer {
  border-color: rgba(255,255,255,0.08);
}

.sb-logo { color: #FFFFFF; }

.sb-footer { color: #8A93B8; }

.sb-toggle {
  border-color: rgba(255,255,255,0.16);
  color: var(--j5-shell-text);
}
.sb-toggle:hover {
  border-color: var(--j5-accent);
  color: #FFFFFF;
}

.sb-search input {
  background: rgba(255,255,255,0.06);
  border-color: rgba(255,255,255,0.1);
  color: #FFFFFF;
}
.sb-search input:focus { border-color: var(--j5-accent); }
.sb-search input::placeholder { color: #6E77A0; }

.sb-section { color: #6E77A0; }

.sb-item { color: var(--j5-shell-text); }
.sb-item:hover {
  background: rgba(255,255,255,0.06);
  color: #FFFFFF;
}
.sb-item.active {
  background: var(--j5-shell-active);
  color: #FFFFFF;
}

.sb-group-hd { color: #FFFFFF; }
.sb-group-hd:hover { background: rgba(255,255,255,0.06); }

.sb-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.14); }

/* ---------- 4. GLOBAL PILLS --------------------------------
   The shadow was tuned for a dark page; on a light canvas it
   read as a smudge. Same geometry, correct weight.
   ----------------------------------------------------------- */
#global-pills > div {
  box-shadow: var(--shadow-sm) !important;
}

#global-credits-pill {
  border-color: #DDD6FE !important;
  background: var(--j5-accent-tint) !important;
}
#global-credits-badge {
  background: var(--j5-accent) !important;
}

/* ---------- 5. AI SURFACES ---------------------------------
   Campaign and comms UI is where the AI shows its work. Violet
   marks it, so approving an AI action never looks like a
   destructive one.
   ----------------------------------------------------------- */
.comms-filter.active {
  background: var(--j5-accent-tint);
  border-color: #DDD6FE;
  color: #6B3FE0;
}

.camp-step-btn.on {
  color: var(--j5-accent);
  border-bottom-color: var(--j5-accent);
}

.camp-chan.on,
.camp-pace.on {
  border-color: var(--j5-accent);
  background: var(--j5-accent-tint);
}

.camp-pace-eta { color: var(--j5-accent); }

.camp-tag:hover {
  border-color: var(--j5-accent);
  color: var(--j5-accent);
}

.camp-card:hover { border-color: var(--j5-accent); }

.camp-bubble { background: var(--red); }

/* ---------- 6. LOGIN ---------------------------------------
   These are inline styles in the markup, so overriding them
   needs !important. Nothing is restructured.
   ----------------------------------------------------------- */
#login-page {
  background: linear-gradient(150deg, #0B1330 0%, #201A4D 55%, #4F46E5 100%) !important;
}

#login-page a,
#forgot-password-modal a {
  color: var(--red) !important;
}

/* ---------- 7. ALERTS --------------------------------------
   .alert-box was hardcoded to the old red, which made every
   notice read as an emergency. Neutral-informational instead;
   real danger still uses --danger.
   ----------------------------------------------------------- */
.alert-box {
  background: var(--info-tint);
  border-color: rgba(23,92,211,0.2);
}
.alert-box h4 { color: var(--info); }

/* ---------- 8. LINKS ---------------------------------------- */
a { color: var(--red); }
a:hover { color: var(--j5-accent); }


/* ============================================================
   9. CRAFT LAYER — layout unchanged, execution elevated
   ------------------------------------------------------------
   Nothing here moves an element to a new place. It changes how
   edges, weight, motion and numerals read. That gap is most of
   what separates a working tool from an expensive one.
   ============================================================ */

/* --- 9.1 Numerals -------------------------------------------
   Metrics that change on refresh must not shift width while
   they do it. Tabular figures also let a column of numbers read
   as a column instead of ragged text. */
.s-val,
.tbl td,
.grind-lbl,
#global-credits-badge,
.pgbtn {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

.s-val {
  letter-spacing: -0.025em;
  line-height: 1.05;
}

/* --- 9.2 Label rhythm ---------------------------------------
   Small caps labels need loose tracking to stay legible; large
   display text needs tight tracking to stay composed. Applying
   both is the cheapest typographic upgrade available. */
.s-label,
.sec-lbl,
.sb-section,
.tbl th {
  letter-spacing: 0.07em;
  font-weight: 700;
}

.page-title {
  letter-spacing: -0.02em;
  font-weight: 800;
}

.page-sub { max-width: 68ch; }

/* --- 9.3 Elevation ------------------------------------------
   One hairline plus one soft shadow, not a heavy border. The
   card should look like it rests on the page rather than being
   drawn onto it. */
.card {
  box-shadow: 0 1px 2px rgba(11,19,48,0.04), 0 1px 1px rgba(11,19,48,0.03);
  transition: box-shadow 160ms cubic-bezier(.4,0,.2,1),
              border-color 160ms cubic-bezier(.4,0,.2,1);
}

.card:hover {
  box-shadow: 0 4px 16px rgba(11,19,48,0.07), 0 1px 2px rgba(11,19,48,0.04);
}

/* --- 9.4 Tables ---------------------------------------------
   Header sits on a faint wash so it reads as chrome, not data.
   Row hover is a tint rather than a border so nothing jumps. */
.tbl th {
  background: #FAFBFD;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
}

.tbl tbody tr {
  transition: background 120ms linear;
}

.tbl tbody tr:hover td {
  background: #FAFBFD;
}

.tbl td { border-bottom: 1px solid #F1F3F8; }

/* --- 9.5 Status pills ---------------------------------------
   Uppercase micro-type at heavy weight, generous radius. Reads
   as a state, not a button. */
.rtag {
  font-weight: 800;
  letter-spacing: 0.04em;
  border-radius: 999px;
  padding: 3px 10px;
}

/* --- 9.6 Motion ---------------------------------------------
   Interactive elements acknowledge the cursor within 120ms.
   Below that threshold an interface feels responsive; above it,
   it feels like it is thinking. */
.sb-item,
.fbtn,
.pgbtn,
.cpybtn,
.camp-card,
.comms-filter,
.upload-btn,
.task-add {
  transition: background 140ms cubic-bezier(.4,0,.2,1),
              color 140ms cubic-bezier(.4,0,.2,1),
              border-color 140ms cubic-bezier(.4,0,.2,1),
              transform 140ms cubic-bezier(.4,0,.2,1);
}

.upload-btn:active,
.task-add:active,
.fbtn:active { transform: translateY(1px); }

/* --- 9.7 Focus ----------------------------------------------
   A visible focus ring is a keyboard user's cursor. The ring is
   the accent at low alpha so it reads as brand, not as an error. */
:focus-visible {
  outline: 2px solid var(--j5-accent);
  outline-offset: 2px;
  border-radius: 6px;
}

.srch:focus,
.task-inp:focus,
input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--j5-accent);
  box-shadow: 0 0 0 3px rgba(124,77,255,0.12);
}

/* --- 9.8 Sidebar detail -------------------------------------
   The active item gets a left marker so the eye finds it before
   reading. Uses an inset shadow, so no box model changes. */
.sb-item.active {
  box-shadow: inset 2px 0 0 var(--j5-accent);
  font-weight: 600;
}

.sb-item { border-radius: 8px; }

/* --- 9.9 Scrollbars ------------------------------------------ */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: #D8DEEC;
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: #C2CADE; background-clip: content-box; }

/* --- 9.10 Empty states --------------------------------------
   An empty table is the most common screen in a new account and
   usually the least designed one. */
.empty {
  color: var(--muted);
  padding: 48px 24px;
}
.empty h3 {
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.01em;
  margin-bottom: 6px;
}

/* --- 9.11 Text quality --------------------------------------- */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

p, .page-sub, .empty { text-wrap: pretty; }

/* --- 9.12 Reduced motion ------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}


/* ============================================================
   10. TODAY TABS — styling for the work-queue tab row
   ============================================================ */
.td-tab {
  display: flex;
  align-items: center;
  gap: 7px;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  padding: 11px 13px;
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  margin-bottom: -1px;
  transition: color 140ms cubic-bezier(.4,0,.2,1),
              border-color 140ms cubic-bezier(.4,0,.2,1);
}
.td-tab:hover { color: var(--text); }
.td-tab.on {
  color: var(--text);
  font-weight: 700;
  border-bottom-color: var(--red);
}

.td-tab-badge {
  border-radius: 999px;
  padding: 1px 7px;
  font-size: 11px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  background: #EEF2FF;
  color: #4338CA;
}
.td-tab-badge.danger { background: #FEE2E2; color: #B91C1C; }
.td-tab-badge.warn   { background: #FEF3C7; color: #92400E; }

/* Panes carry the card; drop the card's own bottom margin so the
   tab row and its content read as one object. */
.td-pane > .card { margin-bottom: 0 !important; }

#td-starthere a { color: #8AD4FF; }


/* ============================================================
   11. WOW LAYER — depth, motion, and a tab bar that follows you
   ------------------------------------------------------------
   Still zero markup changes. Everything here is either a
   transition, a shadow, or a sticky position.
   ============================================================ */

/* --- 11.1 Start here: a slow aurora ---------------------------
   A dark panel with one moving light source reads as lit rather
   than printed. 18s is slow enough that it registers as ambience
   and never as animation. */
#td-starthere {
  position: relative;
  overflow: hidden;
  box-shadow: 0 8px 28px rgba(11,19,48,0.18);
}
#td-starthere::before {
  content: '';
  position: absolute;
  inset: -70%;
  background:
    radial-gradient(46% 60% at 20% 28%, rgba(99,102,241,0.95) 0%, transparent 60%),
    radial-gradient(44% 58% at 76% 68%, rgba(139,92,246,0.9) 0%, transparent 58%),
    radial-gradient(36% 50% at 52% 14%, rgba(34,211,238,0.5) 0%, transparent 56%),
    radial-gradient(34% 46% at 88% 24%, rgba(236,72,153,0.35) 0%, transparent 58%);
  animation: j5aurora 11s ease-in-out infinite alternate;
  pointer-events: none;
  filter: blur(6px);
}

/* A slow sheen crossing the panel — the cue that this surface is live. */
#td-starthere::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  width: 40%;
  left: -50%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,0.13), transparent);
  animation: j5sheen 7s ease-in-out infinite;
  pointer-events: none;
}
@keyframes j5sheen {
  0%, 62% { left: -50%; }
  100%    { left: 120%; }
}
#td-starthere > * { position: relative; z-index: 1; }

@keyframes j5aurora {
  0%   { transform: translate3d(-9%, -7%, 0) scale(1); }
  50%  { transform: translate3d(8%, 9%, 0) scale(1.22) rotate(4deg); }
  100% { transform: translate3d(-5%, 5%, 0) scale(1.1) rotate(-3deg); }
}

#td-starthere button {
  transition: transform 140ms cubic-bezier(.4,0,.2,1), box-shadow 140ms cubic-bezier(.4,0,.2,1);
}
#td-starthere button:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(0,0,0,0.22);
}
#td-starthere button:active { transform: translateY(0); }

/* --- 11.2 Tab bar follows you --------------------------------
   Long queues mean scrolling. A tab bar that scrolls away forces
   a trip back up to change context. */
#td-tabs {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(245,247,251,0.86);
  backdrop-filter: saturate(1.6) blur(10px);
  -webkit-backdrop-filter: saturate(1.6) blur(10px);
  margin-left: -4px;
  padding-left: 4px;
}

.td-tab.on { position: relative; }
.td-tab.on::after {
  content: '';
  position: absolute;
  left: 13px; right: 13px; bottom: -1px;
  height: 2px;
  background: var(--red);
  border-radius: 2px 2px 0 0;
  animation: j5underline 220ms cubic-bezier(.4,0,.2,1);
}
@keyframes j5underline {
  from { transform: scaleX(0.3); opacity: 0; }
  to   { transform: scaleX(1); opacity: 1; }
}

/* --- 11.3 Panes arrive rather than appear --------------------- */
.td-pane { animation: j5pane 260ms cubic-bezier(.16,1,.3,1); }
@keyframes j5pane {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --- 11.4 Hero metrics --------------------------------------
   Three cards carry the morning read. They get a hairline top
   accent that only shows on hover, so the page is calm at rest. */
#page-today .card { position: relative; overflow: hidden; }

#page-today .card::after {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--red), var(--j5-accent));
  opacity: 0;
  transition: opacity 180ms cubic-bezier(.4,0,.2,1);
}
#page-today .card:hover::after { opacity: 1; }

#page-today .card:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 28px rgba(11,19,48,0.09), 0 2px 6px rgba(11,19,48,0.04);
}
#page-today .card {
  transition: transform 200ms cubic-bezier(.16,1,.3,1),
              box-shadow 200ms cubic-bezier(.16,1,.3,1);
}

/* Metrics land instead of blinking in */
#page-today .s-val,
#page-today .s-val-sm {
  animation: j5metric 420ms cubic-bezier(.16,1,.3,1);
}
@keyframes j5metric {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* --- 11.5 Rows respond ---------------------------------------- */
#page-today .tbl tbody tr {
  transition: background 120ms linear, box-shadow 120ms linear;
}
#page-today .tbl tbody tr:hover {
  box-shadow: inset 2px 0 0 var(--j5-accent);
}

/* --- 11.6 Badges pulse once when they change ------------------ */
.td-tab-badge.j5-bump { animation: j5bump 420ms cubic-bezier(.16,1,.3,1); }
@keyframes j5bump {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.28); }
  100% { transform: scale(1); }
}

/* --- 11.7 Keyboard hint --------------------------------------- */
.td-tab kbd {
  display: none;
  font-family: inherit;
  font-size: 9.5px;
  font-weight: 800;
  color: var(--muted);
  background: var(--card2);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 4px;
  margin-left: 2px;
}
body.j5-keys .td-tab kbd { display: inline-block; }

@media (prefers-reduced-motion: reduce) {
  #td-starthere::before { animation: none; }
  .td-pane, .td-tab.on::after,
  #page-today .s-val, #page-today .s-val-sm { animation: none; }
  #page-today .card:hover { transform: none; }
}


/* ============================================================
   12. ACTION HIERARCHY — one primary per row, rest in a menu
   ------------------------------------------------------------
   Seven equally-loud buttons on a row is the same as none. The
   send action is filled, the two next-most-used are outlined,
   and the remaining four sit behind an overflow so the eye has
   one place to land per line.
   ============================================================ */

.j5-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 7px 13px;
  border-radius: 8px;
  font-size: 12.5px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  transition: background 130ms cubic-bezier(.4,0,.2,1),
              border-color 130ms cubic-bezier(.4,0,.2,1),
              color 130ms cubic-bezier(.4,0,.2,1),
              transform 130ms cubic-bezier(.4,0,.2,1);
}
.j5-btn:hover { border-color: #C7CEE2; background: #FAFBFD; }
.j5-btn:active { transform: translateY(1px); }

.j5-btn-primary {
  background: var(--red);
  border-color: var(--red);
  color: #fff;
  font-weight: 700;
  box-shadow: 0 1px 2px rgba(79,70,229,0.24);
}
.j5-btn-primary:hover {
  background: var(--red-dark);
  border-color: var(--red-dark);
}

.j5-btn-icon {
  padding: 7px 9px;
  color: var(--muted);
}
.j5-btn-icon:hover { color: var(--text); }

/* --- Overflow menu ------------------------------------------
   Each item carries a one-line explanation, because "Clear" and
   "Spoke to" mean nothing until someone tells you what they do
   to the list. */
.j5-menu {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 60;
  min-width: 244px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 6px;
  box-shadow: 0 12px 34px rgba(11,19,48,0.14), 0 2px 6px rgba(11,19,48,0.06);
  animation: j5menu 150ms cubic-bezier(.16,1,.3,1);
}
.j5-menu.on { display: block; }

@keyframes j5menu {
  from { opacity: 0; transform: translateY(-4px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.j5-menu button {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: 8px;
  padding: 9px 11px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  line-height: 1.3;
}
.j5-menu button span {
  display: block;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--muted);
  margin-top: 2px;
}
.j5-menu button:hover { background: var(--card2); }
.j5-menu button:hover span { color: var(--text); }

.j5-menu-ok { color: var(--ok) !important; }
.j5-menu-ok:hover { background: #F0FDF4 !important; }

/* Section headings carry an icon now; keep it optically aligned. */
.sec-lbl svg { opacity: .55; }
.s-label svg { opacity: .5; }


/* ============================================================
   13. COMMAND BAND — the top of Today, on one dark surface
   ------------------------------------------------------------
   Restyles existing markup in place. No ids, no handlers, no DOM
   order changed: the greeting, three hero stats, six supporting
   stats and the AI briefing are simply re-presented on dark.

   Why dark: three stacked white bands give the eye no entry
   point. One dark surface reads as chrome — context you glance
   at — which leaves the light half below unambiguously the work.
   ============================================================ */

.j5-band {
  position: relative;
  overflow: hidden;
  background: #0B1024;
  border-radius: var(--r-xl);
  padding: 30px 32px 6px 32px;
  margin-bottom: var(--section-gap);
}

/* Slow-drifting light behind the type. Two blurred radial pools on
   an 11s loop — deliberately below the threshold where motion pulls
   your eye off the list you are working. */
.j5-band::before {
  content: '';
  position: absolute;
  inset: -40% -10% auto -10%;
  height: 150%;
  background:
    radial-gradient(46% 62% at 18% 22%, rgba(99,102,241,.55) 0%, transparent 62%),
    radial-gradient(42% 56% at 74% 8%,  rgba(139,92,246,.42) 0%, transparent 60%),
    radial-gradient(34% 48% at 92% 44%, rgba(34,211,238,.22) 0%, transparent 58%);
  filter: blur(8px);
  pointer-events: none;
  animation: j5drift 11s ease-in-out infinite alternate;
}

@keyframes j5drift {
  from { transform: translate3d(0,0,0) scale(1); }
  to   { transform: translate3d(-3%,2%,0) scale(1.06); }
}

.j5-band-inner { position: relative; z-index: 1; }

/* --- 13.1 Greeting ------------------------------------------
   "Today" demotes to an eyebrow; the greeting becomes the
   headline. Same two elements, inverted hierarchy. */
.j5-band .page-title {
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: #8B93C7;
  margin-bottom: 6px !important;
}

.j5-band .page-sub {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: clamp(26px, 2.6vw, 36px);
  font-weight: 700;
  letter-spacing: -.035em;
  line-height: 1.08;
  color: #fff;
  max-width: 46ch;
}

/* --- 13.2 Buttons on dark ------------------------------------ */
.j5-band button {
  background: rgba(255,255,255,.08) !important;
  border: 1px solid rgba(255,255,255,.16) !important;
  color: #fff !important;
}
.j5-band button:hover { background: rgba(255,255,255,.14) !important; }

/* --- 13.3 The three hero stats -------------------------------
   Cards lose their chrome entirely — on a dark field a border
   around a number is noise. The number carries itself at 52px. */
.j5-band .card {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
}

.j5-band .s-label {
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: #8B93C7;
  margin-bottom: 9px;
}
.j5-band .s-label svg { opacity: .45; }

.j5-band .s-val {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: clamp(38px, 4vw, 52px);
  font-weight: 700;
  letter-spacing: -.04em;
  line-height: 1;
  color: #fff;
}

.j5-band .s-sub {
  font-size: 12.5px;
  font-weight: 500;
  color: #8B93C7;
  margin-top: 6px;
}

/* --- 13.4 The six supporting stats ---------------------------
   The bordered strip becomes a single hairline-topped row: value
   and label side by side, so six numbers read as one line of
   context rather than six small cards. */
.j5-band > .j5-band-inner > div[style*="minmax(140px"] {
  background: transparent !important;
  border: none !important;
  border-top: 1px solid rgba(255,255,255,.08) !important;
  border-radius: 0 !important;
  gap: 0 !important;
  padding-top: 4px;
  margin-bottom: 0 !important;
}

.j5-band > .j5-band-inner > div[style*="minmax(140px"] > div {
  background: transparent !important;
  padding: 14px 0 !important;
}

.j5-band .s-val-sm {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1;
  color: #fff !important;
}

.j5-band > .j5-band-inner > div[style*="minmax(140px"] > div > div:first-child {
  color: #8B93C7 !important;
  font-size: 11px !important;
  font-weight: 700 !important;
  letter-spacing: .05em;
  text-transform: uppercase;
  margin-bottom: 7px !important;
}

.j5-band > .j5-band-inner > div[style*="minmax(140px"] > div > div:not(:first-child):not(.s-val-sm) {
  color: #6E77A8 !important;
  font-size: 11px !important;
  line-height: 1.4;
}

/* --- 13.5 The briefing --------------------------------------
   Already dark, so it drops its own card and sits on a hairline
   inside the band instead of floating as a second dark box. */
.j5-band #td-starthere {
  background: transparent !important;
  border-radius: 0 !important;
  border-top: 1px solid rgba(255,255,255,.08);
  padding: 20px 0 22px 0 !important;
  margin-bottom: 0 !important;
}

.j5-band #td-starthere-text {
  font-size: 15.5px !important;
  font-weight: 500 !important;
  color: #A9B0D6 !important;
  line-height: 1.55 !important;
  max-width: 68ch;
}

.j5-band #td-starthere > div:first-child { display: none; }

.j5-band #td-starthere button:first-of-type {
  background: #fff !important;
  border-color: #fff !important;
  color: #0B1024 !important;
}
.j5-band #td-starthere button:first-of-type:hover { background: #E8EAF6 !important; }

@media (max-width: 900px) {
  .j5-band { padding: 24px 20px 4px 20px; }
}


/* ============================================================
   14. SIDEBAR ICONS — inline SVG in the existing .sb-icon slot
   ------------------------------------------------------------
   The emoji were replaced in place, so every id, onclick and
   role-permission rule still matches. These only size the glyph
   and let it inherit colour — which is the whole point: an
   emoji stays its own colour, so it fights the active state
   instead of joining it.
   ============================================================ */

.sb-icon svg {
  width: 17px;
  height: 17px;
  display: block;
  margin: 0 auto;
  opacity: .72;
  transition: opacity 140ms cubic-bezier(.4,0,.2,1);
}

.sb-item:hover .sb-icon svg,
.sb-group-hd:hover .sb-icon svg { opacity: 1; }

/* The active item's icon takes the accent with its label. */
.sb-item.active .sb-icon svg { opacity: 1; }

.sb-logo {
  letter-spacing: -.01em;
  font-weight: 800;
}

/* Section headers on Today carry icons now; keep them optically
   quieter than the words they sit beside. */
.sec-lbl svg, .s-label svg { opacity: .5; }


/* ============================================================
   15. INLINE ICONS — the .j5i wrapper used app-wide
   ------------------------------------------------------------
   794 emoji across 22 pages were replaced in place with this
   wrapper. It sizes to the surrounding text (1em) and inherits
   colour, which is the whole reason for the swap: an emoji keeps
   its own colour and its own per-device rendering, so it fights
   whatever state its container is in. These join it.

   Deliberately NOT changed: emoji inside <script> — toast copy,
   SMS templates, AI prompts. Those are words people read or
   send, not interface furniture.
   ============================================================ */

.j5i {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.05em;
  height: 1.05em;
  vertical-align: -0.16em;
  flex-shrink: 0;
}

.j5i svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* A trailing gap only when the icon leads a run of text, so icons
   used alone in a button or cell stay optically centred. */
.j5i:not(:only-child) { margin-right: .34em; }

/* In dense table cells the glyph should read a touch quieter than
   the text it labels. */
.tbl .j5i { opacity: .62; }

/* Inside a filled button the icon is already on a solid colour;
   full opacity keeps it legible. */
.j5-btn-primary .j5i, button[style*="#fff"] .j5i { opacity: 1; }

/* Section and stat labels: quiet, since the words carry meaning. */
.sec-lbl .j5i, .s-label .j5i { opacity: .5; }

/* Headings should not shrink their icon below legibility. */
h1 .j5i, h2 .j5i, h3 .j5i, h4 .j5i { width: 1em; height: 1em; opacity: .6; }


/* ============================================================
   16. TAB GROUP LABELS — distinguish the two halves
   ============================================================ */
.j5-grouplbl {
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  align-self: center;
  padding: 0 10px 0 0;
}
.j5-grouplbl-act { color: #4F46E5; padding-left: 2px; }


/* ============================================================
   17. ONE TYPE + CARD SYSTEM, EVERY PAGE
   ------------------------------------------------------------
   The Today page's treatment, promoted to the whole app so a
   prospect clicking Today → Money does not see two products.
   Sizes are set once here; pages inherit rather than declaring
   their own, which is why this is short.
   ============================================================ */

/* --- 17.1 Cards ---------------------------------------------
   One radius, one hairline, one shadow. The 16px radius and the
   two-layer shadow are what read as "expensive" — a single hard
   border reads as a spreadsheet. */
.card {
  border-radius: 16px;
  border: 1px solid var(--border);
  background: var(--card);
  box-shadow: 0 1px 2px rgba(11,19,48,.04), 0 1px 1px rgba(11,19,48,.03);
}

/* --- 17.2 Section headers -----------------------------------
   Sentence case at 15px, not uppercase micro-type: these are
   titles, and titles should read as language. */
.sec-lbl {
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -.01em;
  text-transform: none;
  color: var(--text);
}

/* --- 17.3 Numbers -------------------------------------------
   Every figure in the app on Space Grotesk with tight tracking
   and tabular width, so columns align and nothing shifts on
   refresh. This is the single most legible difference between
   the old pages and Today. */
.s-val, .s-val-sm, .k-val, .kpi-val, .scorecard-val, .grind-lbl {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

.s-val { font-size: clamp(30px, 3vw, 42px); }
.s-val-sm { font-size: 22px; }

/* --- 17.4 Stat labels ---------------------------------------- */
.s-label {
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted);
}

.s-sub {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--muted);
  line-height: 1.5;
}

/* --- 17.5 Tables --------------------------------------------- */
.tbl th {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--muted);
}

.tbl td {
  font-size: 13px;
  font-weight: 500;
}

.tbl td strong, .tbl td b { font-weight: 700; letter-spacing: -.01em; }

/* --- 17.6 Buttons -------------------------------------------
   Every button in the app picks up the row treatment: 8px
   radius, 12.5px semibold, icon and label on one baseline. */
.fbtn, .pgbtn, .cpybtn, .upload-btn, .task-add, .comms-filter {
  border-radius: 8px;
  font-size: 12.5px;
  font-weight: 600;
  font-family: inherit;
  letter-spacing: 0;
}

/* --- 17.7 Page headers --------------------------------------- */
.page-title {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: clamp(24px, 2.4vw, 30px);
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.1;
  text-transform: none;
}

.page-sub {
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
  line-height: 1.55;
  max-width: 68ch;
}

/* The band inverts these two deliberately; keep its rules winning. */
.j5-band .page-title,
.j5-band .page-sub { }


/* ============================================================
   18. COMMAND BAND · DASHBOARD VARIANT
   ------------------------------------------------------------
   The dashboard header uses the same band as Today, with one
   difference: Today's sub-line is a greeting worth setting at
   36px, while the dashboard's is a build stamp. So here the
   headline is its own element and #dash-sub stays small.
   ============================================================ */

.j5-band-dash { padding-bottom: 26px; }

/* The headline. Same face and tracking as Today's greeting. */
.j5-band-head {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: clamp(26px, 2.6vw, 36px);
  font-weight: 700;
  letter-spacing: -.035em;
  line-height: 1.08;
  color: #fff;
  max-width: 46ch;
  margin-bottom: 10px;
}

/* Build stamp and data source: quiet, on one line, not a headline. */
.j5-band-dash .page-sub {
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  font-size: 13px;
  font-weight: 500;
  color: #8B93C7;
  line-height: 1.5;
  max-width: 70ch;
}

.j5-band-dash .page-sub #build-stamp { color: #6E77A8; }

/* The on-hold warning still has to read as a warning on dark. */
.j5-band-dash #on-hold-section { margin-top: 18px; }


/* ============================================================
   19. DASHBOARD KPI TILES — dark, to match the band above them
   ------------------------------------------------------------
   The tiles sit directly under the command band, so putting them
   on the same navy makes the top of the page read as one object
   instead of a dark header with white boxes stapled underneath.

   Colour-coded values (.green/.red/.yellow/.purple/.blue) are
   re-mapped to lighter tints here — the light-mode versions are
   too dark to read on navy, and losing them would lose meaning.
   ============================================================ */

#dash-kpi-row .card,
#dash-kpi-row2 .card {
  background: #0F1533;
  border-color: rgba(255,255,255,.09);
  box-shadow: 0 1px 2px rgba(11,19,48,.18);
}

#dash-kpi-row .card:hover,
#dash-kpi-row2 .card:hover {
  border-color: rgba(255,255,255,.2);
  box-shadow: 0 6px 20px rgba(11,19,48,.28);
}

#dash-kpi-row .s-label,
#dash-kpi-row2 .s-label { color: #8B93C7; }

#dash-kpi-row .s-val,
#dash-kpi-row2 .s-val { color: #fff; }

#dash-kpi-row .s-sub,
#dash-kpi-row2 .s-sub { color: #7A83B4; }

/* Value colours, lightened for a dark ground. */
#dash-kpi-row .s-val.green,  #dash-kpi-row2 .s-val.green  { color: #4ADE80; }
#dash-kpi-row .s-val.red,    #dash-kpi-row2 .s-val.red    { color: #FB7185; }
#dash-kpi-row .s-val.yellow, #dash-kpi-row2 .s-val.yellow { color: #FBBF24; }
#dash-kpi-row .s-val.purple, #dash-kpi-row2 .s-val.purple { color: #C4B5FD; }
#dash-kpi-row .s-val.blue,   #dash-kpi-row2 .s-val.blue   { color: #7DD3FC; }

/* The month-over-month delta line under each headline tile. */
#dash-kpi-row .dash-delta,
#dash-kpi-row2 .dash-delta { color: #7A83B4; }
#dash-kpi-row .dash-delta.green { color: #4ADE80; }
#dash-kpi-row .dash-delta.red   { color: #FB7185; }

/* The green left-rule on Active Members reads too heavy on navy. */
#dash-kpi-row2 .card[style*="border-left"] {
  border-left-color: #4ADE80 !important;
}


/* ============================================================
   20. ADVISOR IN THE BAND
   ------------------------------------------------------------
   "Analyze my numbers" moved from a lone button mid-page into
   the command band, and its report panel now sits directly
   under the band that launched it — so the action and its
   answer are in the same place, on every dashboard tab.
   Same element, same id, same onclick.
   ============================================================ */

.j5-band-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 18px;
}

.j5-band-actions #ai-advisor-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: #fff !important;
  border: none !important;
  color: #0B1024 !important;
  padding: 11px 20px;
  border-radius: 10px;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: none;
  transition: background 140ms cubic-bezier(.4,0,.2,1),
              transform 140ms cubic-bezier(.4,0,.2,1);
}

/* The brain mark, drawn in CSS so the button needs no markup change. */
.j5-band-actions #ai-advisor-btn::before {
  content: '';
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  background: currentColor;
  -webkit-mask: var(--j5-spark) center / contain no-repeat;
  mask: var(--j5-spark) center / contain no-repeat;
}

.j5-band-actions #ai-advisor-btn:hover { background: #E8EAF6 !important; }
.j5-band-actions #ai-advisor-btn:active { transform: translateY(1px); }

.j5-band-actions #ai-advisor-status {
  font-size: 12px;
  font-weight: 500;
  color: #8B93C7;
}

:root {
  --j5-spark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2l2.2 5.6L20 10l-5.2 2L12 18l-2.2-6L4 10l5.8-2.4z'/%3E%3C/svg%3E");
}

/* The report panel, now directly under the band. */
#ai-advisor-panel { margin-top: -4px; margin-bottom: 22px; }
#ai-advisor-panel .card { border-left-width: 3px; }


/* ============================================================
   21. TAB GROUP LABELS — read as labels, not as tabs
   ------------------------------------------------------------
   "Needs you" and "Good to know" were the same size, weight and
   colour as the tabs beside them, so the row looked like ten
   equal buttons. These are captions for the groups, so they get
   a pill treatment the tabs never use — no underline, a tinted
   ground, and smaller type.
   ============================================================ */

#td-tabs > span[style*="text-transform"] {
  font-size: 9.5px !important;
  font-weight: 800 !important;
  letter-spacing: .12em !important;
  border-radius: 999px;
  padding: 4px 10px !important;
  align-self: center;
  line-height: 1;
  white-space: nowrap;
}

/* First label — the work that needs a decision. */
#td-tabs > span[style*="text-transform"]:first-of-type {
  background: #EEF2FF;
  color: #4338CA !important;
  margin-right: 4px;
}

/* Second label — context. Quieter ground, muted ink. */
#td-tabs > span[style*="text-transform"]:last-of-type {
  background: #F1F5F9;
  color: #64748B !important;
  margin-right: 4px;
}

/* The hairline divider between the two groups is a span too —
   exclude it from the pill treatment. */
#td-tabs > span[style*="width:1px"] {
  background: var(--border) !important;
  padding: 0 !important;
  border-radius: 0;
}


/* ============================================================
   22. JFIVE BRANDING
   ------------------------------------------------------------
   The gym is the tenant; JFIVE is the platform underneath it.
   So the gym name stays the headline and the JFIVE mark sits
   beside it as the maker's mark — an app icon next to a
   workspace name, not a competing logo.
   ============================================================ */

.sb-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 2px 0 4px 0;
}

.sb-mark {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  flex-shrink: 0;
  display: block;
  box-shadow: 0 2px 8px rgba(79,70,229,.35);
}

.sb-brand-txt { min-width: 0; }

.sb-logo {
  font-family: 'Space Grotesk', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sb-platform {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 2px;
}

/* Collapsed rail: the mark alone carries the brand. */
.sidebar.collapsed .sb-brand-txt { display: none; }
.sidebar.collapsed .sb-brand { justify-content: center; }
