/* Shared JustSimple sidebar — served from the dashboard container at
   /static/sidebar.css (root path, no prefix, so it resolves the same
   from every service behind Traefik). Edit ONLY here; every page that
   links this file picks up changes automatically. */

:root{
  --ink:#12151c; --muted:#6b7280; --line:#e5e7eb;
  --accent:#1155CC; --brand-red:#e02424;
  --sidebar-w:216px;
  /* Height of the new fixed top bar (Plans & Pricing / Apps &
     Integrations / Services / Unlock free credits / Login) that now
     sits above BOTH the sidebar and the main content on every page --
     see .jsp-topbar below. Sidebar's own `top`/`height` and .jsp-main's
     margin-top are both derived from this one number so they can never
     drift out of sync with the bar's actual height. */
  --topbar-h:68px;
  /* The flat page background every app sits on (base.css's body rule).
     Apps that need to match it for a hover/active state (e.g. an
     export-menu row, a pager button) should reference this instead of
     re-hardcoding #F6F6F7 locally. */
  --bg:#F6F6F7;

  /* Status colors (up/good, warn, down/bad) -- shared across the
     dashboard's Overview donuts, index.css's app cards, and rank
     tracking's stat tiles/change indicators/donut. Single source of
     truth here; no app should redeclare these locally anymore. */
  --good:#1a7f37; --warn:#b58105; --bad:#c0392b;

  /* Shared card/spacing tokens -- DESIGN-CONSISTENCY PASS. Every card
     surface (app-section, teaser-card, app-card, metric-card, ...) and
     every button/pill across every app should reference these instead
     of hardcoding its own radius/padding number, so corner rounding and
     internal spacing can't drift page to page again. */
  --radius-card:12px;   /* big surfaces (Order #1078: flat 12px cards) */
  --radius-tile:12px;   /* inner stat tiles: metric-card, teaser-table-wrap */
  --radius-sm:8px;       /* buttons, inputs, pills, chips */
  --shadow-card:0 1px 2px rgba(18,21,28,.06); /* flat card depth (reference has ~none) */
  --space-card:24px;    /* internal padding for a --radius-card surface */
  --gap-md:16px;         /* standard gap between cards in a grid/row */

  /* Fixed vertical rhythm for the shared hero block (h1 -> subtitle ->
     first card). One set of numbers, used by base.css/overview.css --
     no page should hardcode its own gap between these three.
     TIGHTENED per chat -- h1-to-first-card gap read as too much
     whitespace (Backlink Opportunity vs Rank Tracking's tighter
     reference look); lowered both numbers so every page's hero sits
     closer to its first card, Rank Tracking's spacing is now the
     baseline every other page matches automatically. */
  --stack-title-subtitle:8px;   /* hero-title bottom -> page-subtitle top */
  --stack-subtitle-card:16px;   /* page-subtitle bottom -> first card top */

  /* Shared typography scale -- POLARIS STEP 1 (fonts only).
     Shopify/Polaris base is 14px Inter; hero H1 is 20px/700, section
     titles 16px/600, body 14px/400. Token names are unchanged so every
     per-app var(--font-*) reference keeps working -- only values move
     onto the Polaris scale. */
  --font-family-sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --font-hero:1.25rem;       /* base.css .hero-title: 20px Polaris page H1 */
  --font-section:1rem;       /* card/section titles: 16px Polaris headingMd */
  --font-body:0.875rem;      /* body/table/form text: 14px Polaris base */
  --font-caption:0.75rem;    /* secondary/metadata: 12px Polaris caption */
  --font-stat:1.5rem;        /* "big number" -- 24px Polaris headingXl */
  --font-input:0.875rem;     /* text/url/select inputs: 14px Polaris base */
  --font-btn:0.875rem;       /* primary buttons: 14px Polaris base */
  --weight-heading:600;      /* Polaris semibold headings (order pages use 600, not 700) */
  --weight-hero:700;         /* page H1 only -- Order #1078 titles run bold */

  /* Dark nav shell (Shopify admin frame -- Order #1078 reference):
     pure-black sidebar melting into the black frame; every nav surface
     derives from these so the shell can never drift back. */
  --nav-bg:#000000;
  --nav-ink:#E8EAED;
  --nav-muted:#9AA0A6;
  --nav-dim:#6E747C;
  --nav-hover:rgba(255,255,255,.06);
  --nav-active:rgba(255,255,255,.12);
  --nav-line:rgba(255,255,255,.12);
  --nav-search-bg:rgba(255,255,255,.08);

  /* Single icon column (Order #1078 rail) -- every icon in the rail
     (search magnifier, top-level links, category headers, Pro rows)
     shares one box + one svg size so their left edges line up. */
  --nav-icon-box:22px;
  --nav-icon-size:17px;

  /* Shopify framed shell (Order detail frame) -- outer black outline
     + curved white page card floating inside it. One set of numbers
     so rail + topbar + page can never drift out of sync. */
  --frame-bg:#000000;    /* black outline visible around the whole app */
  --frame-pad:10px;      /* outline thickness on all four sides */
  --frame-radius:20px;   /* outer frame corner rounding */
  --page-radius:16px;    /* white page card corner rounding */
}
/* Collapsed icon-rail mode (body class toggled by sidebar.js) -- every
   shell/content offset derives from --sidebar-w, so one override moves
   sidebar + topbar + .jsp-main together. .jsp-nav-closing is the
   mid-close stage (same narrow width, expanded layout still clipped
   inside) so the fold animates smoothly before the icon-rail layout
   swaps in -- see the toggle handler in sidebar.js. Width/offset
   transitions below run on the shared 350ms [0.4,0,0.2,1] beat, the
   same timing as the toggle-icon path morph. */
body.jsp-nav-collapsed{ --sidebar-w:76px; }
body.jsp-nav-closing{ --sidebar-w:76px; }

.jsp-sidebar{
  position:fixed;
  /* Framed shell: rail floats inside the outer black outline -- inset
     by --frame-pad on all sides, own rounded corners. */
  top:var(--frame-pad);
  left:var(--frame-pad);
  width:var(--sidebar-w);
  height:calc(100vh - 2 * var(--frame-pad));
  height:calc(100dvh - 2 * var(--frame-pad));
  background:var(--nav-bg);
  color:var(--nav-ink);
  padding:16px 6px 24px;
  display:flex;
  flex-direction:column;
  border-right:none;
  border-radius:calc(var(--frame-radius) - 4px);
  overflow-y:auto;
  /* Never allow a horizontal bar: once the vertical bar appears (tall
     nav, e.g. expanded category) it eats layout width on Windows/Linux
     Chrome, which used to push nowrap labels wide enough to trip
     horizontal overflow -- labels already ellipsize by design. */
  overflow-x:hidden;
  scrollbar-width:thin;
  scrollbar-gutter:stable;
  z-index:1000;
  box-sizing:border-box;
  /* Smooth rail fold -- --sidebar-w flips between 216px/76px via the
     body class; the width transition turns that flip into the open/close
     slide (same beat as the toggle-icon morph). */
  transition:width .35s cubic-bezier(.4,0,.2,1);
}
.jsp-sidebar > *{ min-width:0; max-width:100%; }
/* Slim dark-rail scrollbar so Windows matches the macOS overlay look
   instead of the chunky default bar. */
.jsp-sidebar::-webkit-scrollbar{ width:8px; }
.jsp-sidebar::-webkit-scrollbar-track{ background:transparent; }
.jsp-sidebar::-webkit-scrollbar-thumb{ background:rgba(255,255,255,.18); border-radius:8px; }
/* Collapsed rail never scrolls internally (content is icons-only and
   short) so the hover flyout below isn't clipped. */
body.jsp-nav-collapsed .jsp-sidebar{ overflow:visible; }

/* Site-wide top bar -- built + injected by sidebar.js (see
   buildTopbarHTML() there), same "edit once, every app gets it"
   pattern as the sidebar itself. Starts AFTER the full-height dark
   sidebar (Order #1078 frame) instead of spanning the viewport, and
   only holds the functional right-side cluster (Plans & Pricing /
   Services / credits / Sign in) -- the brand mark lives in the
   sidebar now. */
.jsp-topbar{
  position:fixed;
  top:var(--frame-pad); left:calc(var(--frame-pad) + var(--sidebar-w) + var(--frame-pad)); right:var(--frame-pad);
  height:var(--topbar-h);
  background:#fff;
  border-bottom:1px solid var(--line);
  border-radius:var(--page-radius) var(--page-radius) 0 0;
  z-index:1100;
  box-sizing:border-box;
  transition:left .35s cubic-bezier(.4,0,.2,1);
}
.jsp-topbar *{ box-sizing:border-box; }
.jsp-topbar-inner{
  display:flex;
  align-items:center;
  height:100%;
  width:100%;
  padding-left:24px;
}
/* Brand mark -- lives at the top of the dark sidebar (see
   .jsp-sidebar-brand below), not in the topbar. The white chip behind
   the logo guarantees any brand variant (Rankare wordmark, JustSimple
   icon, account-uploaded custom logos which can be any color) stays
   readable on the near-black rail. */
.jsp-sidebar-brand{
  display:flex; align-items:center; gap:10px;
  padding:2px 4px 14px;
  flex:none;
  /* Padding/gap glide with the rail fold -- the brand never snaps. */
  transition:padding .35s cubic-bezier(.4,0,.2,1), gap .3s ease;
}
.jsp-sidebar-brand-chip{
  /* No white box: the logo sits straight on the black rail (a custom logo
     is already repainted in the colour the account picked). */
  background:none; border-radius:10px;
  padding:6px 10px;
  display:flex; align-items:center; justify-content:center;
  flex:1; min-width:0; max-width:220px; overflow:hidden; white-space:nowrap;
  /* Chip collapses + fades with the rail (see collapsed rules below). */
  transition:opacity .22s ease .16s, max-width .35s cubic-bezier(.4,0,.2,1) .03s, padding .3s ease, visibility 0s;
}
.jsp-sidebar-brand-logo{
  display:block; height:26px; width:auto; max-width:100%; object-fit:contain;
}
.jsp-sidebar-brand-logo.is-wordmark{ height:24px; }
/* Default Rankare mark only: flat-white silhouette straight on the
   rail, no chip (reference frame). */
.jsp-sidebar-brand-chip.is-mono{ background:none; }
.jsp-sidebar-brand-logo.is-mono{ filter:brightness(0) invert(1); }
/* Collapse toggle -- mirrors the collapse icon at the top of the
   Order #1078 sidebar. Toggles body.jsp-nav-collapsed (see bottom of
   this file); state persists per browser via localStorage. */
.jsp-sidebar-nav-toggle{
  flex:none; width:32px; height:32px;
  display:flex; align-items:center; justify-content:center;
  background:none; border:1px solid transparent; border-radius:10px;
  color:var(--nav-muted); cursor:pointer; padding:0;
}
.jsp-sidebar-nav-toggle:hover{ background:var(--nav-hover); color:#fff; }
/* Unlumen sidebar-toggle-icon morph (open = wide panel, collapsed =
   narrow column). The inner panel punches through the currentColor
   outer rect using the rail background, and swaps `d` on the same
   350ms [0.4,0,0.2,1] beat as the rail width -- body class is the state
   truth (set by sidebar.js, including the mid-close .jsp-nav-closing
   stage), so icon and rail can never drift apart. Size stays 18px/1.8
   to match the rest of the rail icons. */
.jsp-sidebar-nav-toggle .jsp-nav-toggle-panel{
  fill:var(--nav-bg);
  d:path("M14 6 C14 5.057 14 4.586 13.707 4.293 C13.414 4 12.943 4 12 4 H10 C7.172 4 5.757 4 4.879 4.879 C4 5.757 4 7.172 4 10 V14 C4 16.828 4 18.243 4.879 19.121 C5.757 20 7.172 20 10 20 H12 C12.943 20 13.414 20 13.707 19.707 C14 19.414 14 18.943 14 18 V6 Z");
  transition:d .35s cubic-bezier(.4,0,.2,1);
}
body.jsp-nav-collapsed .jsp-sidebar-nav-toggle .jsp-nav-toggle-panel,
body.jsp-nav-closing .jsp-sidebar-nav-toggle .jsp-nav-toggle-panel{
  d:path("M10 5.5 C10 4.793 10 4.439 9.780 4.220 C9.560 4 9.207 4 8.5 4 H8.5 C6.379 4 5.318 4 4.659 4.659 C4 5.318 4 6.379 4 8.5 V15.5 C4 17.621 4 18.682 4.659 19.341 C5.318 20 6.379 20 8.5 20 H8.5 C9.207 20 9.561 20 9.780 19.780 C10 19.561 10 19.207 10 18.5 V5.5 Z");
}
@media (prefers-reduced-motion:reduce){
  .jsp-sidebar, .jsp-topbar, .jsp-main, .jsp-services-panel{ transition:none; }
  .jsp-sidebar-nav-toggle .jsp-nav-toggle-panel{ transition:none; }
  /* Every staged fade/glide above flips instantly too. */
  .jsp-sidebar *{ transition:none !important; }
}
/* In-page nav filter -- dark input at the top of the rail, same slot
   as the reference sidebar's Search. Client-side only: narrows the
   nav links below as you type (see init() in sidebar.js). */
.jsp-sidebar-search{
  display:flex; align-items:center; gap:10px;
  background:var(--nav-search-bg);
  border:1px solid transparent; border-radius:12px;
  /* Left pad matches the nav rows' own left pad (12px) so the search
     magnifier box starts exactly where every icon box below starts. */
  padding:0 12px 0 12px; height:38px; margin:0 0 12px; flex:none;
  box-sizing:border-box;
  overflow:hidden;
  /* Height/opacity collapse with the rail instead of display:none. */
  transition:height .3s cubic-bezier(.4,0,.2,1), opacity .18s ease, margin .3s ease, padding .3s ease, visibility 0s, border-color .12s, border-width .3s ease;
}
.jsp-sidebar-search:focus-within{ border-color:rgba(255,255,255,.25); background:rgba(255,255,255,.1); }
.jsp-sidebar-search .icon{
  flex:none; width:var(--nav-icon-box); margin-left:calc((var(--nav-icon-size) - var(--nav-icon-box)) / 2);
  display:flex; align-items:center; justify-content:flex-start; color:var(--nav-muted);
}
.jsp-sidebar-search svg{ width:var(--nav-icon-size); height:var(--nav-icon-size); flex:none; display:block; color:var(--nav-muted); }
/* Specificity note: several tool pages style bare input[type=text]
   (0,1,1 -- e.g. audit.css/backlink.css form rules), which would beat a
   lone class selector and paint a light box onto this dark field. The
   .jsp-sidebar ancestor prefix below (0,2,1) keeps the rail's own
   transparent style winning regardless of stylesheet order. */
.jsp-sidebar .jsp-sidebar-search-input{
  flex:1; min-width:0; height:100%;
  background:none; border:none; outline:none; padding:0;
  color:#fff; font-size:0.85rem; font-family:inherit;
}
.jsp-sidebar-search-input::placeholder{ color:var(--nav-muted); }
/* Nav labels fade + collapse with the rail instead of popping. OPEN
   direction (this rule governs it): text stays hidden until the rail is
   mostly open, then fades in. CLOSE direction is governed by the
   collapsed rules below (quick fade first, then hide). max-width -- not
   display -- does the collapsing so it animates; min-width:0 lets the
   flex item actually shrink. */
.jsp-sidebar-link .label,
.jsp-sidebar-cat-header .label,
.jsp-sidebar .jsp-topbar-services-toggle .label,
.jsp-sidebar-account .jsp-topbar-login .t,
.jsp-sidebar-account .jsp-topbar-credits .t,
.jsp-sidebar-account .jsp-topbar-credit-bar-label,
.jsp-topbar-profile-name{
  min-width:0; max-width:220px; overflow:hidden; white-space:nowrap;
  opacity:1; visibility:visible;
  transition:opacity .22s ease .16s, max-width .35s cubic-bezier(.4,0,.2,1) .03s, visibility 0s;
}
.jsp-topbar-nav{
  display:flex;
  align-items:center;
  gap:28px;
  flex:1;
  min-width:0;
}
.jsp-topbar-link{
  color:var(--ink);
  text-decoration:none;
  font-size:0.87rem;
  font-weight:600;
  white-space:nowrap;
}
.jsp-topbar-link:hover{ color:var(--accent); }
.jsp-topbar-right{
  display:flex;
  align-items:center;
  gap:20px;
  flex:none;
  padding-right:28px; /* fixed to the right edge, not tied to .content's gutter */
}
.jsp-topbar-credits{
  display:flex; align-items:center; gap:6px;
  background:#f5f0e2; color:#3a352a;
  padding:9px 16px; border-radius:999px;
  text-decoration:none;
  font-size:0.85rem;
  font-weight:600;
  white-space:nowrap;
  transition:background .12s ease;
}
.jsp-topbar-credits:hover{ background:#ece5d2; text-decoration:none; }
.jsp-topbar .jsp-topbar-credits > span:last-child{ display:flex; align-items:center; }
.jsp-topbar .jsp-topbar-credits svg{ display:block; }
/* Replaces .jsp-topbar-credits once logged in -- see
   buildCreditBarHtml()/refreshCreditBar() in sidebar.js. Orange fill on
   a light track, same visual language as the "10 Credits left" mock. */
.jsp-topbar-credit-bar{
  display:flex; align-items:center; gap:8px;
  white-space:nowrap;
  max-height:40px; overflow:hidden; opacity:1; visibility:visible;
  transition:opacity .22s ease .16s,max-height .35s cubic-bezier(.4,0,.2,1) .03s,visibility 0s;
}
.jsp-topbar-credit-bar-track{
  width:64px; height:6px; flex:none;
  border-radius:999px;
  background:#fbe3d3;
  overflow:hidden;
}
.jsp-topbar-credit-bar-fill{
  height:100%;
  border-radius:999px;
  background:#f2652b;
  transition:width .3s ease;
}
.jsp-topbar-credit-bar-label{
  font-size:0.82rem;
  font-weight:600;
  color:var(--ink);
}
/* Fully spent -- fill goes neutral grey instead of orange so it reads
   as "empty", not just "a bit low". */
.jsp-topbar-credit-bar--exhausted .jsp-topbar-credit-bar-fill{ background:#d1d5db; }
.jsp-topbar-credit-bar--exhausted .jsp-topbar-credit-bar-label{ color:var(--muted); }
/* Logged-in credits dropdown (cream pill): shows the AI balance, with
   the per-pool breakdown in the dropdown. Cream tokens are hardcoded
   here (this file predates the --badge-* tokens): bg #f5f0e2, hover
   #ece5d2, ink #3a352a -- same values as dev. */
.jsp-topbar-credits-drop{ position:relative; }
.jsp-topbar-credit-pill{
  display:flex; align-items:center; gap:8px;
  background:#f5f0e2; color:#3a352a;
  border:none; border-radius:999px;
  height:40px; padding:0 16px;
  font-family:inherit; font-size:0.85rem; font-weight:600;
  white-space:nowrap; cursor:pointer;
  transition:background .12s ease;
}
.jsp-topbar-credit-pill:hover{ background:#ece5d2; }
.jsp-credit-coin{ display:flex; flex:none; }
.jsp-credit-coin svg{ width:15px; height:15px; display:block; }
.jsp-topbar-credit-text{ display:flex; align-items:center; }
.jsp-topbar-credit-side{ display:flex; align-items:baseline; gap:5px; }
.jsp-topbar-credit-side.is-hidden{ display:none; }
.jsp-topbar-credit-count{ font-weight:700; }
.jsp-topbar-credit-pool{ font-weight:600; }
.jsp-credit-drop-chev{ display:flex; flex:none; }
.jsp-credit-drop-chev svg{ display:block; width:14px; height:14px; transition:transform .26s cubic-bezier(.22,1,.36,1); }
.jsp-topbar-credit-pill[aria-expanded="true"] .jsp-credit-drop-chev svg,
.jsp-topbar-credit-pill.is-open .jsp-credit-drop-chev svg{ transform:rotate(180deg); }
.jsp-topbar-credit-pill--exhausted{ opacity:.65; }
.jsp-credit-drop-row{ padding:10px 14px; }
.jsp-credit-drop-row-top{ display:flex; justify-content:space-between; gap:10px; font-size:0.82rem; font-weight:600; color:var(--ink); }
.jsp-credit-drop-track{ height:6px; border-radius:999px; background:rgba(17,23,32,.08); margin:8px 0 6px; overflow:hidden; }
.jsp-credit-drop-fill{ height:100%; border-radius:inherit; background:var(--accent); }
.jsp-credit-drop-sub{ font-size:0.75rem; color:var(--muted); }
.jsp-credit-drop-menu{
  display:none;
  background:#f5f0e2; border:none; border-radius:14px;
  box-shadow:0 20px 48px rgba(17,23,32,.14);
  overflow:hidden;
  transform-origin:top right;
}
.jsp-credit-drop-menu.open{ display:block; }
.jsp-topbar-login{
  /* Blue pill, matching --accent, for consistency with the primary buttons
     used everywhere else in the app (Run Audit, etc.). */
  background:var(--accent);
  color:#fff;
  text-decoration:none;
  font-size:0.85rem;
  font-weight:700;
  padding:9px 22px;
  border-radius:999px;
  white-space:nowrap;
  display:inline-flex; align-items:center;
  transition:opacity .12s;
}
.jsp-topbar-login:hover{ opacity:.85; }

/* Services mega-dropdown -- layout copied from the NP Digital/Ubersuggest
   reference (left category list, 2-col focus-area grid, promo card on the
   right) but re-skinned blue (var(--accent)) instead of the reference's
   orange. All copy inside is still placeholder (AAA/BBB/...) -- see
   buildServicesPanelHTML() in sidebar.js. */
.jsp-topbar-services{ position:relative; }
/* Services toggle inside the dark rail: same wrap/toggle classes as the
   old topbar instance (so initServicesDropdown is untouched), restyled
   as a full-width nav row. The fixed mega-panel anchors the same as
   before (top under the topbar, left after the rail). */
.jsp-sidebar .jsp-topbar-services-toggle{
  width:100%;
  justify-content:flex-start;
  gap:10px;
  padding:9px 12px;
  border-radius:12px;
  color:var(--nav-ink);
  font-size:0.88rem;
  font-weight:600;
  text-decoration:none;
  white-space:nowrap;
  background:none;
  border:none;
  font-family:inherit;
  cursor:pointer;
  text-align:left;
  transition:padding .35s cubic-bezier(.4,0,.2,1),gap .3s ease;
}
.jsp-sidebar .jsp-topbar-services-toggle:hover{ background:var(--nav-hover); color:#fff; }
.jsp-sidebar .jsp-topbar-services-toggle .icon{
  flex:none; width:var(--nav-icon-box); text-align:center;
  display:flex; align-items:center; justify-content:center;
  color:var(--nav-muted);
}
.jsp-sidebar .jsp-topbar-services-toggle .icon svg{ width:var(--nav-icon-size); height:var(--nav-icon-size); display:block; }
.jsp-sidebar .jsp-topbar-services-toggle:hover .icon{ color:#fff; }
.jsp-sidebar .jsp-topbar-services-toggle .label{ flex:1; text-align:left; min-width:0; overflow:hidden; }
.jsp-nav-collapsed .jsp-sidebar .jsp-topbar-services-toggle{ padding:10px 21px; gap:0; }
.jsp-nav-collapsed .jsp-sidebar .jsp-topbar-services-toggle .label,
.jsp-nav-collapsed .jsp-sidebar .jsp-topbar-services-chevron{
  max-width:0; opacity:0; visibility:hidden;
  transition:opacity .13s ease,max-width .3s cubic-bezier(.4,0,.2,1),visibility 0s linear .13s;
}
.jsp-topbar-services-toggle{
  display:flex; align-items:center; gap:5px;
  background:none; border:none; padding:0; margin:0;
  font-family:inherit; cursor:pointer;
}
.jsp-topbar-services-chevron{ flex:none; max-width:24px; overflow:hidden; opacity:1; visibility:visible; transition:transform .26s cubic-bezier(.22,1,.36,1),opacity .22s ease .16s,max-width .35s cubic-bezier(.4,0,.2,1) .03s,visibility 0s; color:var(--muted); }
.jsp-topbar-services-toggle[aria-expanded="true"] .jsp-topbar-services-chevron{ transform:rotate(180deg); color:var(--accent); }
.jsp-topbar-services-toggle[aria-expanded="true"]{ color:var(--accent); }

.jsp-services-panel{
  display:none;
  position:fixed;
  top:var(--topbar-h);
  /* Centered on the dashboard's content region (right of the rail),
     not the whole viewport: margin auto centers within the left/right
     offsets, which track --sidebar-w so the collapsed rail recenters
     automatically. Deliberately NOT transform:translateX, which would
     fight animatePanel()'s own y/scale transform mid-animation. */
  left:calc(var(--frame-pad) + var(--sidebar-w) + var(--frame-pad));
  right:var(--frame-pad);
  margin-inline:auto;
  width:min(920px, calc(100vw - var(--sidebar-w) - 3 * var(--frame-pad) - 32px));
  max-height:calc(100vh - var(--topbar-h) - 24px);
  overflow-y:auto;
  background:#fff;
  border:1px solid var(--line);
  border-top:none;
  box-shadow:0 20px 48px rgba(17,23,32,.14);
  border-radius:0 0 16px 16px;
  z-index:1200;
  transition:left .35s cubic-bezier(.4,0,.2,1);
}
.jsp-services-panel.open{ display:block; }
.jsp-services-inner{ display:flex; align-items:stretch; }

.jsp-services-col-heading{
  font-size:0.68rem; font-weight:700; color:var(--muted);
  text-transform:uppercase; letter-spacing:.08em; margin-bottom:12px;
}

/* Left: category list (matches the NP Digital "Offers" list -- icon,
   label, chevron; active/hover row gets a soft blue highlight) */
.jsp-services-col-cats{
  width:220px; flex:none; padding:22px 14px; border-right:1px solid var(--line);
}
.jsp-services-col-cats .jsp-services-col-heading{
  font-size:1rem; font-weight:800; color:var(--ink); text-transform:none;
  letter-spacing:normal; margin-bottom:6px;
}
.jsp-services-col-sub{ font-size:0.82rem; color:var(--accent); font-weight:700; margin:0 0 10px 2px; }
.jsp-services-cat-list{ display:flex; flex-direction:column; gap:4px; }
.jsp-services-cat{
  display:flex; align-items:center; gap:12px;
  width:100%; text-align:left; background:none; border:none; border-radius:10px;
  padding:11px 12px; font-family:inherit; font-size:0.9rem; font-weight:600;
  color:var(--ink); cursor:pointer; transition:background .12s,color .12s;
}
.jsp-services-cat-icon{ flex:none; display:flex; color:var(--accent); }
.jsp-services-cat-name{ flex:1; }
.jsp-services-cat-chevron{ flex:none; opacity:0; transition:opacity .12s; color:var(--accent); }
.jsp-services-cat:hover{ background:rgba(17,85,204,.08); }
.jsp-services-cat.active{ background:rgba(17,85,204,.1); color:var(--accent); }
.jsp-services-cat.active .jsp-services-cat-chevron,
.jsp-services-cat:hover .jsp-services-cat-chevron{ opacity:1; }

/* Middle: focus-area grid */
.jsp-services-col-focus{ flex:1; min-width:0; padding:22px 26px; }
.jsp-services-focus-grid{
  display:grid; grid-template-columns:1fr 1fr; gap:20px 32px;
}
.jsp-services-focus-item{
  display:block; text-decoration:none; cursor:pointer;
  padding:10px; margin:-10px; border-radius:10px;
  transition:background .12s;
}
.jsp-services-focus-item:hover{ background:rgba(17,23,32,.045); }
.jsp-services-focus-item h4{ margin:0 0 5px; font-size:0.92rem; font-weight:700; color:var(--ink); }
.jsp-services-focus-item p{ margin:0; font-size:0.82rem; line-height:1.45; color:var(--muted); }

/* Right: promo card */
.jsp-services-col-promo{
  width:250px; flex:none; padding:22px; background:rgba(17,85,204,.06);
  border-left:1px solid var(--line); border-radius:0 0 16px 0;
}
.jsp-services-promo-avatar{
  width:44px; height:44px; border-radius:50%; background:rgba(17,85,204,.15);
  display:flex; align-items:center; justify-content:center; font-size:1.2rem; margin-bottom:12px;
}
.jsp-services-promo-title{ font-size:1rem; font-weight:800; color:var(--accent); margin-bottom:8px; line-height:1.3; }
.jsp-services-promo-body{ font-size:0.82rem; line-height:1.5; color:var(--muted); margin:0 0 16px; }
.jsp-services-promo-btn{
  display:block; width:100%; box-sizing:border-box; text-align:center;
  background:var(--accent); color:#fff; text-decoration:none; border:none; border-radius:8px;
  padding:11px 14px; font-size:0.82rem; font-weight:700; letter-spacing:.02em;
  cursor:pointer; transition:opacity .12s;
}
.jsp-services-promo-btn:hover{ opacity:.88; }

@media (max-width:820px){
  .jsp-services-panel{ display:none !important; } /* mega-dropdown doesn't have a compact layout yet -- topbar nav is already hidden below this breakpoint */
}

.jsp-sidebar *{ box-sizing:border-box; }
/* Sections breathe with whitespace only (reference rail) -- no divider lines. */
.jsp-sidebar-section{ margin:0 0 14px; padding-bottom:14px; }
.jsp-sidebar-section-label{
  font-size:0.68rem; font-weight:700; color:var(--muted);
  text-transform:uppercase; letter-spacing:.08em; padding:0 10px 8px;
  max-height:40px; overflow:hidden; white-space:nowrap; opacity:1; visibility:visible;
  transition:opacity .22s ease .16s,max-height .35s cubic-bezier(.4,0,.2,1) .03s,padding .3s ease,visibility 0s;
}
.jsp-sidebar-nav{ display:flex; flex-direction:column; gap:2px; }
.jsp-sidebar-link{
  display:flex; align-items:center; gap:10px; padding:9px 12px; border-radius:12px;
  color:var(--nav-ink); text-decoration:none; font-size:0.88rem; font-weight:600;
  /* Padding/gap glide the icon to center as the rail folds -- no
     justify-content snap. */
  transition:background .12s,color .12s,padding .35s cubic-bezier(.4,0,.2,1),gap .3s ease;
}
.jsp-sidebar-link:hover{ background:var(--nav-hover); color:#fff; }
.jsp-sidebar-link.active{ background:var(--nav-active); color:#fff; }
.jsp-sidebar-link .icon{ font-size:1rem; flex:none; width:var(--nav-icon-box); text-align:center; display:flex; align-items:center; justify-content:center; }
.jsp-sidebar-link .icon svg{ width:var(--nav-icon-size); height:var(--nav-icon-size); display:block; }
/* Nav icons are monochrome (Order #1078 rail) -- the SVGs use
   currentColor, so one rule tones them all: muted at rest, white on
   hover/active. */
.jsp-sidebar-link .icon{ color:var(--nav-muted); }
.jsp-sidebar-cat-header .icon{ color:inherit; }
.jsp-sidebar-link:hover .icon{ color:#fff; }
.jsp-sidebar-link.active .icon{ color:#fff; }
/* Pro group (Services / Consulting / Plans) -- flat Channels/Apps-style
   group: plain muted "Pro" label on top, three always-visible rows
   below. NOT a collapsible .jsp-sidebar-cat (no toggle/children) --
   the rows below are plain .jsp-sidebar-link so they line up with
   Overview, not indented like tool-category children. */
.jsp-sidebar-group-label{
  font-size:0.8rem; font-weight:600; color:var(--nav-muted);
  /* Left edge lines up with the icon GLYPHS above (not the row box):
     row padding 12px + half the (22px box - 17px glyph) centering. */
  padding:0 12px 6px calc(12px + (var(--nav-icon-box) - var(--nav-icon-size)) / 2);
  margin:0; display:block;
  letter-spacing:.01em; text-transform:none; line-height:1.43;
  max-height:40px; overflow:hidden; white-space:nowrap; opacity:1; visibility:visible;
  transition:opacity .22s ease .16s,max-height .35s cubic-bezier(.4,0,.2,1) .03s,padding .3s ease,margin .3s ease,visibility 0s;
}
/* Services toggle row inside Pro: a <button>, so it needs explicit
   font inheritance to read exactly like the two <a> rows below it
   (buttons don't inherit type from their parent by default). */
.jsp-sidebar-pro .jsp-topbar-services-toggle{
  background:none; border:none; font:inherit; cursor:pointer;
  text-align:left; width:100%;
  color:var(--nav-muted);
}
.jsp-sidebar-pro .jsp-topbar-services-toggle:hover{ background:none; color:#fff; }
.jsp-sidebar-pro .jsp-topbar-services-toggle .label{ flex:1; text-align:left; }
.jsp-sidebar-pro .jsp-topbar-services-toggle .icon{ color:var(--nav-muted); }
.jsp-sidebar-pro .jsp-topbar-services-toggle:hover .icon{ color:#fff; }
/* All three Pro rows copy the top-5 category headers' look exactly
   (0.8rem/600 muted, NO pill, text just brightens on hover) -- they
   are plain .jsp-sidebar-link elements, so the base link rules
   (0.88rem bright ink + pill hover) must be overridden here. The
   active Consulting row still gets the white pill via the rule below. */
.jsp-sidebar-pro .jsp-sidebar-link{
  font-size:0.8rem; font-weight:600; letter-spacing:.01em; padding:8px 12px;
  color:var(--nav-muted); background:none; border-radius:12px;
}
.jsp-sidebar-pro .jsp-sidebar-link:hover{ background:none; color:#fff; }
.jsp-sidebar-pro .jsp-sidebar-link:hover .icon{ color:#fff; }
.jsp-sidebar-pro .jsp-sidebar-link.active{ background:var(--nav-active); color:#fff; }
.jsp-sidebar-pro .jsp-sidebar-link.active .icon{ color:#fff; }
.jsp-sidebar-link .label{ flex:1; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }

/* Category header (Analyze and Audit / AI Search Visibility / ...) --
   looks like a nav link but is a <button>, since clicking it only
   toggles the child list open/closed rather than navigating. */
.jsp-sidebar-categories{ display:flex; flex-direction:column; gap:2px; }
/* Category header (Analyze and Audit / AI Search Visibility / ...) --
   plain muted section title like the reference rail's Channels/Apps
   labels -- not a button-looking row. Still a <button> that toggles
   the child list (chevron is the affordance); text brightens on
   hover/expand instead of gaining a pill. */
.jsp-sidebar-cat-header{
  width:100%; display:flex; align-items:center; gap:10px; padding:8px 12px; border-radius:8px;
  background:none; border:none; color:var(--nav-muted); font-size:0.8rem; font-weight:600;
  font-family:inherit; cursor:pointer; text-align:left; letter-spacing:.01em;
  transition:color .12s,padding .35s cubic-bezier(.4,0,.2,1),gap .3s ease;
}
.jsp-sidebar-cat-header:hover{ background:none; color:#fff; }
.jsp-sidebar-cat.expanded > .jsp-sidebar-cat-header{ color:#fff; }
.jsp-sidebar-cat-header .icon{ font-size:1rem; flex:none; width:var(--nav-icon-box); text-align:center; display:flex; align-items:center; justify-content:center; }
.jsp-sidebar-cat-header .icon svg{ width:var(--nav-icon-size); height:var(--nav-icon-size); display:block; }
.jsp-sidebar-cat-header .label{ flex:1; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.jsp-sidebar-cat-header .chevron{
  flex:none; font-size:0.9rem; color:var(--nav-muted);
  max-width:24px; overflow:hidden; opacity:1; visibility:visible;
  /* Matches the list's own open duration (DUR_OPEN in sidebar.js) so
     the arrow leads the expand/collapse by the same beat. Base glyph
     points down; expanded rotates to up. Opacity/max-width fade the
     chevron with the rail fold (close timing overridden below). */
  transition:transform .32s cubic-bezier(.22,1,.36,1),opacity .22s ease .16s,max-width .35s cubic-bezier(.4,0,.2,1) .03s,visibility 0s;
}
.jsp-sidebar-cat-header .chevron svg{ display:block; }
.jsp-sidebar-cat.expanded > .jsp-sidebar-cat-header .chevron{ transform:rotate(180deg); }

/* Category with no live sub-items yet (Competitive Research) --
   not a button, not clickable, just a label + "Soon" badge. */
.jsp-sidebar-cat-header.disabled{
  cursor:default; color:var(--nav-dim);
}
.jsp-sidebar-cat-header.disabled .icon{ opacity:.5; }
.jsp-sidebar-cat-header .soon{
  flex:none; font-size:0.62rem; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  color:var(--nav-muted); background:rgba(255,255,255,.08);
  padding:2px 7px; border-radius:100px;
  max-width:70px; overflow:hidden; white-space:nowrap; opacity:1; visibility:visible;
  transition:opacity .22s ease .16s,max-width .35s cubic-bezier(.4,0,.2,1) .03s,padding .3s ease,visibility 0s;
}

/* Sub-items -- collapsed by default, shown once the parent .jsp-sidebar-cat
   carries .expanded (either the user clicked the header, or init()
   auto-expanded it because the current page lives in this category). */
.jsp-sidebar-children{
  display:none; flex-direction:column; gap:2px;
  padding-left:14px; margin-top:2px;
  /* Numeric cap (never binding in practice) so the rail fold can ease
     the open categories shut instead of snapping them. The Motion One
     dropdown animation drives inline height, which always stays under
     this cap, so the two never fight. */
  max-height:1400px; opacity:1; visibility:visible;
  transition:opacity .18s ease,max-height .3s cubic-bezier(.4,0,.2,1),margin .3s ease,visibility 0s;
}
.jsp-sidebar-cat.expanded > .jsp-sidebar-children{ display:flex; }
.jsp-sidebar-child{ font-size:0.84rem; font-weight:500; padding:8px 12px; }

/* Lockable child items (currently: AI Search Visibility's Prompts/Brands/
   Sentiment before any check has been run) -- still clickable, the app
   itself redirects to Overview with an explanatory flash, this is just a
   visual cue so the click doesn't feel broken. See sidebar.js initLockableItems(). */
.jsp-sidebar-child .lock-icon{ display:none; flex:none; font-size:0.72rem; opacity:.55; }
.jsp-sidebar-child.locked{ color:#b4b8c0; }
.jsp-sidebar-child.locked:hover{ color:var(--muted); }
.jsp-sidebar-child.locked .lock-icon{ display:inline; }

/* Every page's own content should sit inside <div class="jsp-main"> --
   framed shell: curved white page card floating inside the outer
   black outline. Fixed between topbar and frame bottom with its own
   inner scroll, so the rounded corners + black gutter stay pinned
   while content slides underneath (Shopify Order-detail frame). */
.jsp-main{
  position:fixed;
  top:calc(var(--frame-pad) + var(--topbar-h));
  bottom:var(--frame-pad);
  left:calc(var(--frame-pad) + var(--sidebar-w) + var(--frame-pad));
  right:var(--frame-pad);
  margin:0;
  background:#fff;
  border-radius:0 0 var(--page-radius) var(--page-radius);
  box-shadow:0 8px 28px rgba(0,0,0,.28);
  box-sizing:border-box;
  overflow-y:auto;
  overflow-x:hidden;
  transition:left .35s cubic-bezier(.4,0,.2,1);
}

/* Public, un-authenticated results pages (seo-audit's and
   ai-search-visibility's own /<domain> route, see each app's
   base.html -- body only ever gets this class when that route's
   public_url is set). sidebar.js's init() already skips building the
   sidebar/.jsp-topbar entirely on these pages (window.JSP_BARE_PAGE),
   so #jsp-sidebar-slot stays an empty, non-fixed div -- this just
   removes the margin/min-height .jsp-main normally reserves for that
   chrome, so the result content sits flush at the top of the viewport
   instead of leaving a blank gap where the sidebar/topbar would have
   been. */
body.jsp-bare .jsp-main{
  top:var(--frame-pad);
  bottom:var(--frame-pad);
  left:var(--frame-pad);
  right:var(--frame-pad);
  /* No rail/topbar on bare pages, so the card takes the full frame. */
  border-radius:var(--page-radius);
}

/* Print/export (Overview "Export" button -> window.print()): drop the
   black frame + shadows so pages print on white, not ink. */
@media print{
  body{ background:#fff !important; padding:0 !important; }
  .jsp-sidebar, .jsp-topbar{ display:none !important; }
  .jsp-main{
    position:static !important; margin:0 !important; overflow:visible !important;
    border-radius:0 !important; box-shadow:none !important;
  }
}

@media (max-width:820px){
  :root{ --sidebar-w:72px; }
  /* Only room for the Sign in button at this width -- the middle nav
     links and "Unlock free credits" drop off rather than wrap/overlap. */
  .jsp-topbar-nav{ display:none; }
  .jsp-topbar-right{ padding-right:16px; }
  /* Brand column shrinks along with the sidebar below it -- crop the
     wide wordmark down to just its icon and drop the tagline text,
     same treatment the sidebar's own copy used to get. */
  .jsp-topbar-brand{ width:var(--sidebar-w); padding:0; align-items:center; justify-content:center; }
  .jsp-topbar-brand-logo{
    width:36px; height:36px;
    object-fit:cover; object-position:right center;
  }
  /* Wordmark logo (Rankare default): show it whole, not cropped to its
     right edge like the icon logos above. */
  .jsp-topbar-brand-logo.is-wordmark{ width:60px; height:auto; max-width:100%; object-fit:contain; }
  .jsp-topbar-brand-tagline{ display:none; }
  .jsp-sidebar-link .label,.jsp-sidebar-section-label{ display:none; }
  .jsp-sidebar .jsp-topbar-services-toggle .label,
  .jsp-sidebar .jsp-topbar-services-chevron{ display:none; }
  .jsp-sidebar .jsp-topbar-services-toggle{ justify-content:center; padding:10px 0; }
  /* Compact rail: account rows collapse to icons (body prefix beats
     the end-of-file base rules on equal specificity ties). */
  body .jsp-sidebar-account .jsp-topbar-credit-bar{ display:none; }
  body .jsp-sidebar-account .jsp-topbar-login,
  body .jsp-sidebar-account .jsp-topbar-credits{ font-size:0; justify-content:center; padding:9px 0; }
  body .jsp-sidebar-account .jsp-topbar-login::after{ margin:0; }
  body .jsp-sidebar-account .jsp-topbar-credits span:last-child{ font-size:0.95rem; margin:0; }
  body .jsp-sidebar-account .jsp-topbar-profile-toggle{ justify-content:center; }
  body .jsp-sidebar-account .jsp-topbar-profile-toggle span{ display:none; }
  .jsp-sidebar-link{ justify-content:center; padding:10px 0; }
  .jsp-sidebar-link .icon{ font-size:1.2rem; }
  .jsp-sidebar-link .icon svg{ width:19px; height:19px; }

  /* Category header labels/chevron/badge have no room at icon-only
     width, and sub-items (jsp-sidebar-child) carry no icon of their
     own -- collapsing them here would make that whole category
     unreachable on mobile. So: force every category permanently open
     and icon-only, same as the top-level links above. */
  .jsp-sidebar-cat-header .label,
  .jsp-sidebar-cat-header .chevron,
  .jsp-sidebar-cat-header .soon{ display:none; }
  .jsp-sidebar-cat-header{ justify-content:center; padding:10px 0; }
  .jsp-sidebar-cat-header .icon{ font-size:1.2rem; }
  .jsp-sidebar-cat-header .icon svg{ width:19px; height:19px; }
  .jsp-sidebar-children{ display:flex !important; padding-left:0; }
  .jsp-sidebar-child{ justify-content:center; padding:8px 0; font-size:0.7rem; text-align:center; }
}

/* ============================================================
   Login modal -- opened by the top bar's "Sign in" link (see
   initLoginModal() in sidebar.js). Two-column card: left = the actual
   email/Google form, right = a light-grey feature panel, matching the
   layout referenced in chat, re-skinned for JustSimple (blue accent
   instead of that reference's orange, our own feature list instead of
   its copy). LAYOUT ONLY right now -- see the big comment in
   sidebar.js above initLoginModal() for what's intentionally NOT wired
   up yet.
   ============================================================ */
.jsp-modal-overlay{
  position:fixed; inset:0;
  background:rgba(15,17,23,.55);
  display:none;
  align-items:center; justify-content:center;
  padding:24px;
  z-index:2000;
  box-sizing:border-box;
}
.jsp-modal-overlay.open{ display:flex; }
/* Prevent the page behind the modal from scrolling while it's open. */
body.jsp-modal-open{ overflow:hidden; }

.jsp-login-modal{
  position:relative;
  display:flex;
  width:100%;
  max-width:960px;
  max-height:90vh;
  overflow-y:auto;
  background:#fff;
  border-radius:24px;
  box-shadow:0 24px 64px rgba(0,0,0,.28);
}
.jsp-login-modal *{ box-sizing:border-box; }

.jsp-login-close{
  position:absolute; top:16px; right:16px;
  width:32px; height:32px;
  display:flex; align-items:center; justify-content:center;
  background:none; border:none; border-radius:50%;
  font-size:1.4rem; line-height:1; color:var(--muted);
  cursor:pointer; z-index:1;
}
.jsp-login-close:hover{ background:rgba(0,0,0,.06); color:var(--ink); }

.jsp-login-left{
  flex:1 1 50%;
  min-width:0;
  padding:44px 40px;
}
.jsp-login-title{
  margin:0 0 26px;
  font-size:1.5rem;
  font-weight:800;
  line-height:1.32;
  color:var(--ink);
}
.jsp-login-title-accent{ color:var(--accent); }

.jsp-login-google-wrap{ position:relative; margin-bottom:22px; }
.jsp-login-google{
  width:100%;
  display:flex; align-items:center; justify-content:center; gap:12px;
  background:var(--accent);
  color:#fff;
  border:none; border-radius:9px;
  padding:13px 16px;
  font-size:0.88rem; font-weight:700; letter-spacing:.02em; text-transform:uppercase;
  cursor:pointer;
  transition:opacity .12s;
}
.jsp-login-google:hover{ opacity:.9; }
.jsp-login-google-icon{
  display:flex; align-items:center; justify-content:center;
  width:26px; height:26px; flex:none;
  background:#fff; border-radius:5px;
}
.jsp-login-lastused{
  position:absolute; top:-11px; right:14px;
  background:#fff; color:var(--accent);
  border:1px solid var(--accent);
  font-size:0.62rem; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  padding:3px 10px; border-radius:100px;
}

.jsp-login-divider{
  display:flex; align-items:center; gap:12px;
  color:var(--muted); font-size:0.84rem;
  margin:24px 0;
}
.jsp-login-divider::before, .jsp-login-divider::after{
  content:''; flex:1; height:1px; background:var(--line);
}

.jsp-login-field{ margin-bottom:16px; }
.jsp-login-field label{
  display:block; font-weight:700; font-size:0.82rem; margin-bottom:6px; color:var(--ink);
}
.jsp-login-field input{
  width:100%; padding:12px 14px;
  border:1px solid var(--line); border-radius:8px;
  font-size:0.92rem; color:var(--ink);
  font-family:inherit;
}
.jsp-login-field input:focus{ outline:none; border-color:var(--accent); }

.jsp-login-password-wrap{ position:relative; }
.jsp-login-password-wrap input{ padding-right:44px; }
.jsp-login-eye, .jsp-subuser-eye{
  position:absolute; top:50%; right:12px; transform:translateY(-50%);
  background:none; border:none; cursor:pointer;
  font-size:1rem; line-height:1; color:var(--muted); opacity:.6;
  padding:4px;
}
.jsp-login-eye.is-visible, .jsp-subuser-eye.is-visible{ opacity:1; color:var(--accent); }

.jsp-login-row{
  display:flex; align-items:center; justify-content:space-between;
  margin:4px 0 24px;
  font-size:0.86rem;
}
.jsp-login-remember{
  display:flex; align-items:center; gap:8px;
  color:var(--ink); cursor:pointer;
}
.jsp-login-remember input{ margin:0; }
.jsp-login-link{
  color:var(--accent);
  text-decoration:underline;
  font-weight:600;
  white-space:nowrap;
}

.jsp-login-submit{
  width:100%;
  background:var(--accent); color:#fff;
  border:none; border-radius:8px;
  padding:14px;
  font-size:0.92rem; font-weight:700; letter-spacing:.02em; text-transform:uppercase;
  cursor:pointer;
  transition:opacity .12s;
}
.jsp-login-submit:hover{ opacity:.9; }

.jsp-login-footer{
  text-align:center;
  margin:18px 0 0;
  font-size:0.88rem;
  color:var(--ink);
}
/* Left-side type matches the showcase title (Inter 500, tight) -- one
   override so labels, buttons, footer and title can't drift apart. */
.jsp-login-left .jsp-login-title,
.jsp-login-left label,
.jsp-login-left input,
.jsp-login-left button,
.jsp-login-left a,
.jsp-login-left p,
.jsp-login-left span{
  font-weight:500; letter-spacing:-.02em;
  font-feature-settings:"ss01","cv11";
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
}
/* Title only: a touch thicker than the form text. */
.jsp-login-left .jsp-login-title{ font-weight:600; }
/* Same treatment for the logged-out actions. */
.jsp-float-credits .jsp-topbar-login,
.jsp-float-credits .jsp-topbar-credits,
.jsp-trial-cta{
  font-weight:600; letter-spacing:-.02em;
  font-feature-settings:"ss01","cv11";
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
}

.jsp-login-right{
  flex:1 1 50%;
  min-width:0;
  background:#fff;
  padding:8px;
  display:flex; flex-direction:column;
  border-top-right-radius:24px; border-bottom-right-radius:24px;
}
.jsp-login-right-inner{
  position:relative;
  overflow:hidden;
  flex:1;
  background:#F5F5F7;
  border-radius:16px;
  padding:44px 36px;
  display:flex; flex-direction:column; justify-content:center;
}
/* Mesh wash borrowed from the pricing-card palette. */
.jsp-login-right-inner::before{
  content:""; position:absolute; inset:0; border-radius:inherit;
  background:
    radial-gradient(100% 80% at 10% 55%, rgba(74,144,245,.4) 0%, transparent 70%),
    radial-gradient(70% 55% at 70% 70%, rgba(184,181,245,.35) 0%, transparent 65%),
    radial-gradient(100% 90% at 100% 100%, rgba(79,70,229,.4) 0%, transparent 75%);
  pointer-events:none;
}
.jsp-login-right-inner > *{ position:relative; }
.jsp-login-modal > .jsp-login-close{ display:none; }
.jsp-login-right-inner.jsp-login-photo{
  background:
    radial-gradient(120% 90% at 50% 38%, rgba(255,255,255,.8) 0%, rgba(255,255,255,0) 60%),
    linear-gradient(165deg, #8B9BF2 0%, #B7C0F7 45%, #E9EBFD 100%);
  padding:30px 28px;
  display:flex; flex-direction:column;
}
.jsp-login-photo-logo{ align-self:flex-end; margin-bottom:16px; }
.jsp-login-photo-logo img{ height:28px; width:auto; display:block; filter:brightness(0) invert(1); }
.jsp-login-illus-card{
  background:none;
  padding:4px;
  margin-bottom:20px;
}
.jsp-login-illus{ width:100%; height:auto; display:block; mix-blend-mode:multiply; }
.jsp-login-photo-title{
  margin:0;
  font-family:var(--font-family-sans);
  font-size:clamp(2rem, 4vw, 2.8rem); font-weight:500; line-height:1; letter-spacing:-.02em;
  color:#fff; text-align:right;
}

@media (max-width:720px){
  /* Feature panel drops off below tablet width -- just the form,
     full-width, same treatment the top bar's own nav links get. */
  .jsp-login-right{ display:none; }
  .jsp-login-modal{ max-width:460px; }
  .jsp-login-left{ padding:40px 28px; }
}

/* ============================================================
   Plans & Pricing modal -- opened by the top bar's "Plans & Pricing"
   link (see initPricingModal() in sidebar.js). Reuses .jsp-modal-overlay
   for the backdrop/open behavior, own .jsp-pricing-modal card. Three
   grey tiers with per-card gradient wash, dot + name header, giant
   price, full-width CTA (black-filled for the popular tier) and a
   white inset checklist -- tier prices/quotas/copy still live in
   PRICING_PLANS in sidebar.js. Monthly/Yearly toggle only, no
   Lifetime tier.
   ============================================================ */
.jsp-pricing-modal{
  position:relative;
  width:100%;
  max-width:1120px;
  max-height:90vh;
  overflow-y:auto;
  background:#fff;
  border-radius:20px;
  box-shadow:0 24px 64px rgba(0,0,0,.28);
  padding:44px 40px 40px;
  box-sizing:border-box;
  scrollbar-width:none;
}
.jsp-pricing-modal::-webkit-scrollbar{ display:none; }
.jsp-pricing-modal *{ box-sizing:border-box; }
.jsp-pricing-modal{
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  font-feature-settings:"ss01","cv11";
}

.jsp-pricing-close{
  position:absolute; top:34px; right:34px; display:flex;
  width:40px; height:40px; font-size:1.6rem;
  margin:0; z-index:5;
  background:rgba(30,30,34,.55); color:#fff;
  border:1px solid rgba(255,255,255,.18);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
}
.jsp-pricing-close:hover{ background:rgba(30,30,34,.75); color:#fff; }

.jsp-pricing-head{
  display:flex; flex-direction:column; align-items:center;
  gap:20px;
  margin-bottom:32px;
  text-align:center;
}
.jsp-pricing-title{
  margin:0;
  font-size:1.6rem;
  font-weight:500;
  letter-spacing:-.02em;
  color:var(--ink);
}

/* Monthly/Yearly toggle -- pill-shaped selector, active side filled
   with the accent color (this is the "orange -> blue" swap from the
   reference: the reference's selected-tab underline/border was
   orange, ours is var(--accent)). */
.jsp-pricing-toggle{
  display:inline-flex;
  background:var(--bg);
  border-radius:100px;
  padding:4px;
  gap:2px;
}
.jsp-pricing-toggle-btn{
  border:none;
  background:none;
  padding:9px 24px;
  border-radius:100px;
  font-size:0.86rem;
  font-weight:700;
  color:var(--muted);
  cursor:pointer;
  transition:background .12s, color .12s;
}
.jsp-pricing-toggle-btn.active{
  background:#111;
  color:#fff;
}

.jsp-pricing-grid{
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:var(--gap-md);
  align-items:stretch;
}

.jsp-pricing-card{
  position:relative;
  border:none;
  border-radius:8px;
  background:#F5F5F7;
  padding:28px 24px 24px;
  display:flex;
  flex-direction:column;
}
/* Full-strength bottom wash per tier, matched to the reference fade
   curve (clean top, saturated tint at the bottom edge). Order follows
   PRICING_PLANS (basic, pro, elite) -- no markup hooks needed. */
.jsp-pricing-card::before{
  content:""; position:absolute; inset:0; border-radius:inherit;
  background:
    radial-gradient(100% 85% at 0% 100%, rgba(196,85,232,.65) 0%, rgba(166,76,240,.35) 45%, transparent 75%),
    radial-gradient(70% 55% at 100% 45%, rgba(127,214,232,.55) 0%, transparent 70%);
  pointer-events:none;
}
.jsp-pricing-grid > :nth-child(2) .jsp-pricing-card::before{
  background:
    radial-gradient(100% 80% at 10% 55%, rgba(74,144,245,.65) 0%, transparent 70%),
    radial-gradient(70% 55% at 70% 70%, rgba(184,181,245,.5) 0%, transparent 65%),
    radial-gradient(100% 90% at 100% 100%, rgba(79,70,229,.65) 0%, transparent 75%);
}
.jsp-pricing-grid > :nth-child(3) .jsp-pricing-card::before{
  background:
    radial-gradient(100% 80% at 0% 100%, rgba(92,200,224,.65) 0%, transparent 70%),
    radial-gradient(70% 55% at 100% 20%, rgba(168,235,207,.65) 0%, transparent 65%);
}
.jsp-pricing-card > *{ position:relative; }
.jsp-pricing-top{ display:flex; align-items:center; gap:10px; margin-bottom:14px; }
.jsp-pricing-dot{
  flex:none; width:22px; height:22px; border-radius:50%;
  background:#ECECF0; display:inline-flex; align-items:center; justify-content:center;
}
.jsp-pricing-dot::after{ content:""; width:8px; height:8px; border-radius:50%; background:#111; }
.jsp-pricing-name{ margin:0; font-size:1.5rem; font-weight:500; letter-spacing:-.01em; color:var(--ink); }
.jsp-pricing-price{ display:flex; align-items:baseline; gap:6px; }
.jsp-pricing-price .amount{ font-size:3.25rem; font-weight:500; letter-spacing:-.02em; color:var(--ink); }
.jsp-pricing-price .period{ font-size:1.5rem; font-weight:500; color:var(--muted); }
.jsp-pricing-billed{ font-size:0.78rem; color:var(--muted); margin:2px 0 0; min-height:1.1em; }
.jsp-pricing-tagline{ margin:10px 0 20px; font-size:1rem; line-height:1.5; min-height:3em; color:#5F6573; }

.jsp-pricing-cta{
  width:100%;
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  background:transparent; color:var(--ink);
  border:1.5px solid #111; border-radius:6px;
  padding:15px 16px;
  font-size:0.9375rem; font-weight:500;
  cursor:pointer;
  transition:background .15s ease, color .15s ease;
}
.jsp-pricing-cta svg{ width:16px; height:16px; flex:none; }
.jsp-pricing-cta:hover{ background:#111; color:#fff; }
.jsp-pricing-note{ margin:10px 0 0; font-size:0.74rem; line-height:1.5; min-height:3em; color:var(--muted); text-align:center; }

/* White inset checklist with black check circles. */
.jsp-pricing-features{
  list-style:none; margin:18px 0 0; padding:18px;
  background:rgba(255,255,255,.85);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
  border-radius:8px;
  display:flex; flex-direction:column; gap:12px;
  flex:1;
}
.jsp-pricing-features li{
  display:flex; align-items:flex-start; gap:10px;
  font-size:0.875rem;
  color:#2B2F3A;
  line-height:1.45;
}
.jsp-pricing-features .tick{ flex:none; width:20px; height:20px; border-radius:50%; background:#111; color:#fff; margin-top:1px; display:inline-flex; align-items:center; justify-content:center; }
.jsp-pricing-features .tick svg{ width:12px; height:12px; display:block; }

@media (max-width:920px){
  .jsp-pricing-grid{ grid-template-columns:1fr; }
  .jsp-pricing-modal{ padding:36px 24px 32px; }
}
/* ============================================================
   "Out of credits" modal -- popped automatically, site-wide, by the
   global fetch interceptor in sidebar.js the moment any app's paid
   call gets refused for a $0 balance (see initCreditModal()). Small,
   single-purpose centered card -- reuses .jsp-modal-overlay for the
   backdrop, its own compact .jsp-credit-modal card (not the big
   login/pricing layouts, since this only needs one line of context +
   one CTA).
   ============================================================ */
.jsp-credit-modal{
  position:relative;
  width:100%;
  max-width:380px;
  background:#fff;
  border-radius:20px;
  box-shadow:0 24px 64px rgba(0,0,0,.28);
  padding:40px 32px 32px;
  box-sizing:border-box;
  text-align:center;
}
.jsp-credit-modal *{ box-sizing:border-box; }
.jsp-credit-close{ position:absolute; top:16px; right:16px; }

.jsp-credit-icon{
  width:52px; height:52px; margin:0 auto 18px;
  border-radius:50%; background:rgba(17,85,204,.1);
  color:var(--accent);
  display:flex; align-items:center; justify-content:center;
}
.jsp-credit-title{
  margin:0 0 10px; font-size:1.2rem; font-weight:800; color:var(--ink);
}
.jsp-credit-body{
  margin:0 0 24px; font-size:0.9rem; line-height:1.55; color:var(--muted);
}
.jsp-credit-cta{
  width:100%; background:var(--accent); color:#fff; border:none; border-radius:10px;
  padding:13px 16px; font-size:0.92rem; font-weight:700; letter-spacing:.01em;
  cursor:pointer; transition:opacity .12s;
}
.jsp-credit-cta:hover{ opacity:.88; }
/* Applied by sidebar.js's applyCreditGate() to any [data-jsp-credit-gate]
   element (Search/Load-more/etc buttons) once a logged-in user's free
   credit hits $0 -- on top of the browser's own :disabled dimming, this
   adds a "why is this greyed out" cue via the not-allowed cursor + a
   subtle strike-through-free faded look, so it doesn't just look broken.
   The element's own `title` (set alongside this class in sidebar.js)
   supplies the actual "Out of credits" tooltip text. */
[data-jsp-credit-gate].jsp-credit-gated{
  opacity:.5;
  cursor:not-allowed !important;
}

/* -- Switch User / Add User rows inside the topbar profile menu (see
   sidebar.js's buildProfileHtml() subUserSectionHtml, and the
   .jsp-subuser-* click handlers in initLoginModal()). Most of each
   row's own layout is inline-styled at generation time in JS (kept
   there so a single template string stays self-contained); just the
   hover/active affordances live here. -- */
.jsp-subuser-row:hover{ background:#f9fafb; }
.jsp-subuser-row.is-active{ font-weight:700; color:#2563eb !important; }
.jsp-subuser-delete:hover{ color:#dc2626 !important; }
.jsp-topbar-add-user:hover{ background:#f9fafb; }

/* ============================================================
   Collapsed icon-rail mode (body.jsp-nav-collapsed, toggled by the
   sidebar brand-row button -- Order #1078's collapsible nav).
   --sidebar-w is already overridden to 76px on the body, so the
   topbar + .jsp-main follow automatically; everything below fades and
   glides instead of snapping: labels/chevrons/badges collapse via
   max-width (never display:none, which can't transition), rows glide
   their padding so icons ride to center, and open categories fold via
   max-height. CLOSE timing lives here (fast fade, then hide);
   OPEN timing lives on the base rules (reveal late in the slide).
   Links themselves are untouched -- same hrefs, same
   active/lockable handling.
   ============================================================ */
/* Brand keeps its row layout when collapsed (chip fades away, toggle
   glides to center) -- no flex-direction restack snap. */
.jsp-nav-collapsed .jsp-sidebar-brand{ gap:0; padding:2px 16px 14px; align-items:center; }
.jsp-nav-collapsed .jsp-sidebar-brand-chip{
  max-width:0; opacity:0; visibility:hidden; padding:6px 0;
  transition:opacity .13s ease,max-width .3s cubic-bezier(.4,0,.2,1),padding .25s ease,visibility 0s linear .13s;
}
.jsp-nav-collapsed .jsp-sidebar-brand-logo{ height:24px; }
.jsp-nav-collapsed .jsp-sidebar-search{
  height:0; opacity:0; visibility:hidden; margin:0;
  padding-top:0; padding-bottom:0; border-width:0;
  transition:height .3s cubic-bezier(.4,0,.2,1),opacity .13s ease,margin .3s ease,padding .3s ease,visibility 0s linear .13s,border-color .12s,border-width .3s ease;
}
.jsp-nav-collapsed .jsp-sidebar-link .label,
.jsp-nav-collapsed .jsp-sidebar-cat-header .label,
.jsp-nav-collapsed .jsp-sidebar-cat-header .chevron,
.jsp-nav-collapsed .jsp-sidebar-cat-header .soon,
.jsp-nav-collapsed .jsp-sidebar-section-label,
.jsp-nav-collapsed .jsp-sidebar-group-label{
  max-width:0; opacity:0; visibility:hidden;
  transition:opacity .13s ease,max-width .3s cubic-bezier(.4,0,.2,1),padding .25s ease,visibility 0s linear .13s;
}
.jsp-nav-collapsed .jsp-sidebar-cat-header .soon{ padding-left:0; padding-right:0; }
.jsp-nav-collapsed .jsp-sidebar-section-label,
.jsp-nav-collapsed .jsp-sidebar-group-label{
  max-height:0; margin:0; padding-top:0; padding-bottom:0; overflow:hidden;
  transition:opacity .13s ease,max-height .3s cubic-bezier(.4,0,.2,1),padding .25s ease,margin .25s ease,visibility 0s linear .13s;
}
/* Rows keep flex-start: icons glide to center via padding alone. */
.jsp-nav-collapsed .jsp-sidebar-link,
.jsp-nav-collapsed .jsp-sidebar-cat-header{ padding:10px 21px; gap:0; }
/* Open categories fold shut with the rail instead of vanishing. */
.jsp-nav-collapsed .jsp-sidebar-children{
  max-height:0; opacity:0; visibility:hidden; margin-top:0; overflow:hidden;
  transition:opacity .13s ease,max-height .3s cubic-bezier(.4,0,.2,1),margin .3s ease,visibility 0s linear .13s;
}
.jsp-nav-collapsed .jsp-sidebar-cat{ position:relative; }
.jsp-nav-collapsed .jsp-sidebar-cat:hover .jsp-sidebar-children{
  display:flex !important;
  position:absolute; left:calc(100% + 10px); top:0;
  background:#242428;
  border:1px solid rgba(255,255,255,.1);
  border-radius:12px; padding:8px; min-width:210px;
  z-index:1300; box-shadow:0 16px 40px rgba(0,0,0,.45);
  max-height:none; opacity:1; visibility:visible; overflow:visible; margin-top:0;
  transition:opacity .15s ease;
}
.jsp-nav-collapsed .jsp-sidebar-children .jsp-sidebar-child{ justify-content:flex-start; gap:8px; padding:9px 12px; }
.jsp-nav-collapsed .jsp-sidebar-children .label{ display:inline !important; }
.jsp-nav-collapsed .jsp-sidebar-cat:hover .jsp-sidebar-children .label{
  max-width:220px; opacity:1; visibility:visible;
  transition:opacity .15s ease,max-width .25s ease,visibility 0s;
}
/* Mid-animation hold (added by sidebar.js for BOTH directions): keep
   everything clipped and the flyout off until the slide settles, so no
   scrollbar or pop-in flickers mid-motion. */
body.jsp-nav-animating .jsp-sidebar{ overflow:hidden !important; }

/* ============================================================
   No-topbar frame (body.jsp-no-topbar, always set in init()): the
   credits/Sign in cluster moved to the rail bottom, so the emptied
   topbar hides and content starts at the viewport top -- the
   reference frame has no top bar. Inline light-bg styles on the
   moved cluster (profile toggle, credit labels) get dark-rail
   overrides here; all refresh logic is location-independent.
   ============================================================ */
body.jsp-no-topbar .jsp-topbar{ display:none; }
/* No-topbar frame: topbar hidden, so the page card rises to the frame
   pad (not to viewport top) and keeps its top rounding. */
body.jsp-no-topbar .jsp-main{
  top:var(--frame-pad);
  border-radius:var(--page-radius);
}
body.jsp-no-topbar .jsp-services-panel{ top:12px; }
.jsp-sidebar-account{
  margin-top:auto;
  padding:14px 0 0;
  display:flex; flex-direction:column; gap:10px;
}
.jsp-sidebar-account .jsp-topbar-right{
  display:flex; flex-direction:column; align-items:stretch; gap:10px;
  padding:0;
}
.jsp-sidebar-account .jsp-topbar-login{
  background:none; border:none;
  color:var(--nav-muted); font-size:0.8rem; font-weight:600;
  display:flex; align-items:center; gap:10px;
  padding:9px 12px; border-radius:8px; text-decoration:none; white-space:nowrap;
  transition:padding .35s cubic-bezier(.4,0,.2,1),gap .3s ease;
}
.jsp-sidebar-account .jsp-topbar-login:hover{ background:var(--nav-hover); color:#fff; opacity:1; }
.jsp-sidebar-account .jsp-topbar-login::after{
  content:""; width:15px; height:15px; flex:none; margin-left:auto;
  background:no-repeat center/contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M4 12h15M13 6l6 6-6 6' stroke='%239AA0A6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.jsp-sidebar-account .jsp-topbar-login:hover::after{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M4 12h15M13 6l6 6-6 6' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.jsp-sidebar-account .jsp-topbar-credits{
  color:var(--nav-muted); font-size:0.8rem; font-weight:600;
  display:flex; align-items:center; gap:10px;
  padding:9px 12px; border-radius:8px; text-decoration:none; white-space:nowrap;
  transition:padding .35s cubic-bezier(.4,0,.2,1),gap .3s ease;
}
.jsp-sidebar-account .jsp-topbar-credits span:last-child{ margin-left:auto; display:flex; color:var(--nav-muted); }
.jsp-sidebar-account .jsp-topbar-credits:hover{ background:var(--nav-hover); color:#fff; text-decoration:none; }
.jsp-sidebar-account .jsp-topbar-credits:hover span{ color:#fff; }
.jsp-sidebar-account .jsp-topbar-credit-bar-label{ color:var(--nav-ink); }
/* Profile pill layout lives here (moved from inline styles in
   buildProfileHtml) so the collapsed rail can glide it like any other
   row. Rendering is identical in the topbar context. */
.jsp-topbar-profile-toggle{
  display:flex; align-items:center; gap:8px; background:none; border:none;
  cursor:pointer; padding:4px 6px; border-radius:20px;
  transition:padding .35s cubic-bezier(.4,0,.2,1),gap .3s ease;
}
.jsp-topbar-profile-name{ max-width:160px; }
.jsp-sidebar-account .jsp-topbar-profile-toggle span{ color:#fff !important; }
/* Compact rail: icon rows glide to center and text fades (back on
   expand), profile shows avatar only. No display:none anywhere -- every
   hide is a staged fade, so nothing pops mid-slide. */
.jsp-nav-collapsed .jsp-sidebar-account .jsp-topbar-credit-bar{
  max-height:0; opacity:0; visibility:hidden; overflow:hidden;
  transition:opacity .13s ease,max-height .3s cubic-bezier(.4,0,.2,1),visibility 0s linear .13s;
}
.jsp-nav-collapsed .jsp-sidebar-account .jsp-topbar-login,
.jsp-nav-collapsed .jsp-sidebar-account .jsp-topbar-credits{ padding:9px 25px; gap:0; }
.jsp-nav-collapsed .jsp-sidebar-account .jsp-topbar-login::after{ margin:0; }
.jsp-nav-collapsed .jsp-sidebar-account .jsp-topbar-credits span:last-child{ margin:0; }
.jsp-nav-collapsed .jsp-sidebar-account .jsp-topbar-profile-toggle{ padding:4px 18px; gap:0; }
.jsp-nav-collapsed .jsp-sidebar-account .jsp-topbar-profile-name{
  max-width:0; opacity:0; visibility:hidden;
  transition:opacity .13s ease,max-width .3s cubic-bezier(.4,0,.2,1),visibility 0s linear .13s;
}
/* Profile dropup menu (ChatGPT-style card in rail tokens) -- every row
   keeps its class, copy and gating; only the container is reskinned.
   Inline display:none/block stays: the outside-click closer depends
   on it (see sidebar.js). */
.jsp-topbar-profile-menu{
  background:#1d1f24;
  border:1px solid rgba(255,255,255,.1);
  border-radius:14px;
  box-shadow:0 16px 48px rgba(0,0,0,.5);
  padding:8px;
  overflow:hidden;
}
.jsp-profile-menu-head{
  display:flex; align-items:center; gap:10px;
  padding:8px; border-radius:10px;
}
.jsp-profile-menu-avatar{ display:flex; flex:none; }
.jsp-profile-menu-id{ display:flex; flex-direction:column; min-width:0; flex:1; }
.jsp-profile-menu-name{
  font-size:0.85rem; font-weight:600; color:#fff;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.jsp-profile-menu-plan{ font-size:0.75rem; color:var(--nav-muted); }
.jsp-profile-menu-chev{ display:flex; flex:none; color:var(--nav-muted); }
.jsp-profile-menu-chev svg{ width:14px; height:14px; display:block; }
.jsp-profile-menu-div{ height:1px; background:rgba(255,255,255,.1); margin:6px 4px; }
.jsp-topbar-profile-menu button:hover{ background:rgba(255,255,255,.08); }
.jsp-topbar-profile-menu button{ background:none; transition:background .12s ease, color .12s ease; }
.jsp-profile-menu-ic{ display:flex; flex:none; color:#b9bec7; }
.jsp-profile-menu-ic svg{ width:16px; height:16px; display:block; }
/* Compact rail: the card would squeeze into 76px, so it floats as an
   overlay panel to the right of the rail instead. */
.jsp-nav-collapsed .jsp-topbar-profile-menu,
.jsp-nav-closing .jsp-topbar-profile-menu{ left:0; right:auto; width:224px; }
/* "What are credits?" guidance popover (Unlock pill, logged-out only)
   -- anchored white card under the floating pill, reference layout in
   our tokens. */
.jsp-credit-info-wrap{ display:none; position:fixed; width:320px; max-width:calc(100vw - 24px); z-index:1150; }
.jsp-credit-info-wrap.open{ display:block; }
.jsp-credit-info{
  background:#fff; border:1px solid var(--line); border-radius:16px;
  box-shadow:0 16px 48px rgba(18,21,28,.2);
  padding:22px 18px 18px; text-align:center;
}
.jsp-credit-info *{ box-sizing:border-box; }
.jsp-credit-info-motif{
  display:inline-flex; align-items:center; justify-content:center;
  width:52px; height:52px; border-radius:50%;
  background:rgba(17,85,204,.1); color:var(--accent);
  margin-bottom:10px;
}
.jsp-credit-info-motif svg{ width:26px; height:26px; display:block; }
.jsp-credit-info-title{ margin:0 0 8px; font-size:1rem; font-weight:800; color:var(--ink); }
.jsp-credit-info-body{ margin:0 0 4px; font-size:0.82rem; line-height:1.55; color:var(--muted); }
.jsp-credit-info-dismiss{
  background:none; border:none; cursor:pointer; padding:4px 8px;
  font-size:0.82rem; font-weight:700; color:var(--accent); font-family:inherit;
}
.jsp-credit-info-dismiss:hover{ text-decoration:underline; }
.jsp-credit-info-div{ height:1px; background:var(--line); margin:12px 0; }
.jsp-credit-info-allow{ margin:0 0 12px; font-size:0.8rem; font-weight:600; color:var(--ink); }
.jsp-credit-info-cta{
  display:flex; align-items:center; justify-content:center;
  width:100%; border:none; cursor:pointer;
  background:var(--accent); color:#fff;
  font-size:0.85rem; font-weight:700; font-family:inherit;
  padding:11px 12px; border-radius:10px;
  transition:opacity .12s;
}
.jsp-credit-info-cta:hover{ opacity:.88; }
/* Soft landing for logged-in rail elements (profile pill + credit bars)
   -- they pop in after the login roundtrip; this makes the swap read
   as a glide instead of a snap. Element-level, so it covers cached
   first paint and live swaps with no JS changes. */
@keyframes jsp-rail-in{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }
.jsp-topbar-profile,
.jsp-topbar-credit-bar{ animation:jsp-rail-in .25s ease; }
@media (prefers-reduced-motion:reduce){
  .jsp-topbar-profile, .jsp-topbar-credit-bar{ animation:none; }
}
/* Logged-out floating "Unlock free credits" pill (top-right of the
   dashboard) + bottom-left trial promo card -- Ubersuggest-style
   placement in our Atlas tokens. Design-only: both reuse the existing
   login-modal triggers, no new flows. */
.jsp-float-credits{
  position:fixed;
  top:calc(var(--frame-pad) + 14px);
  right:calc(var(--frame-pad) + 28px);
  z-index:1150;
  display:flex; align-items:center; gap:10px;
}
body .jsp-float-credits .jsp-topbar-credits{
  background:rgba(17,85,204,.1);
  border:1px solid rgba(17,85,204,.35);
  color:var(--accent);
  border-radius:999px;
  padding:9px 16px;
}
body .jsp-float-credits .jsp-topbar-credits:hover{ text-decoration:none; background:rgba(17,85,204,.16); }
body .jsp-float-credits .jsp-topbar-credits span:last-child{ display:flex; align-items:center; }
body .jsp-float-credits .jsp-topbar-credits svg{ display:block; }
body .jsp-float-credits .jsp-topbar-login{
  background:var(--accent); color:#fff;
  border-radius:999px;
}
body .jsp-float-credits .jsp-topbar-login:hover{ opacity:.88; }
/* After login the pill slot hosts the real credit bars instead. */
body .jsp-float-credits .jsp-topbar-credit-bar{
  background:#fff;
  border:1px solid var(--line);
  border-radius:999px;
  box-shadow:0 8px 24px rgba(18,21,28,.12);
  padding:8px 14px;
}
.jsp-trial-card{
  background:#fff;
  border:1px solid var(--line);
  border-radius:14px;
  box-shadow:0 10px 28px rgba(18,21,28,.16);
  margin:12px 12px 0;
  padding:16px 12px 14px;
  text-align:center;
}
.jsp-trial-icon{
  display:inline-flex; align-items:center; justify-content:center;
  width:36px; height:36px; border-radius:50%;
  background:rgba(17,85,204,.12); color:var(--accent);
  margin-bottom:8px;
}
.jsp-trial-icon svg{ width:18px; height:18px; display:block; }
.jsp-trial-title{
  margin:0 0 12px; font-size:1rem; font-weight:800; line-height:1.3;
  color:var(--accent);
}
.jsp-trial-cta{
  display:flex; align-items:center; justify-content:center; gap:8px;
  width:100%; border:none; cursor:pointer;
  background:var(--accent); color:#fff;
  font-size:0.82rem; font-weight:700; font-family:inherit;
  padding:10px 12px; border-radius:8px;
  transition:opacity .12s;
  white-space:nowrap;
}
.jsp-trial-cta:hover{ opacity:.88; }
/* Compact rail has no room for the promo card (Sign in row stays). */
.jsp-nav-collapsed .jsp-trial-card,
.jsp-nav-closing .jsp-trial-card{ display:none; }
/* === Rankare-preserved rules (billing banner, pricing ribbon, login features, card search) kept from rankare branch === */
/* Popular tier: no outline -- the black POPULAR pill already marks it,
   so the card keeps the clean borderless look of its siblings. */
.jsp-pricing-card.popular{
  border-color:transparent;
  box-shadow:none;
}
.jsp-login-features{
  list-style:none; margin:0; padding:0;
  display:flex; flex-direction:column; gap:26px;
}
.jsp-login-feature-icon{
  flex:none;
  width:44px; height:44px;
  display:flex; align-items:center; justify-content:center;
  border-radius:50%;
  border:1px solid var(--line);
  background:#fff;
}
.jsp-login-feature-icon svg{ width:20px; height:20px; }
.jsp-billing-banner-close{
  flex:none; border:none; background:none; cursor:pointer;
  color:var(--muted); font-size:1.3rem; line-height:1; padding:0 2px;
}
.jsp-billing-banner-msg{ flex:1; }
.jsp-billing-banner-msg{ flex:1 1 100%; }
.jsp-billing-banner-btn{
  flex:none; border:none; cursor:pointer;
  background:var(--accent); color:#fff;
  border-radius:var(--radius-sm); padding:8px 14px;
  font-size:0.82rem; font-weight:700;
}
.jsp-billing-banner-btn:disabled{ opacity:.6; cursor:default; }
/* Billing banner (past_due / ended) -- see renderBillingBanner() in sidebar.js */
.jsp-billing-banner{
  position:fixed; left:50%; bottom:20px; transform:translateX(-50%);
  z-index:9000; max-width:min(640px, calc(100vw - 32px));
  display:flex; align-items:center; gap:14px;
  background:#fff; color:var(--ink);
  border:1px solid var(--line); border-left:4px solid var(--warn);
  border-radius:12px; padding:12px 14px 12px 16px;
  box-shadow:0 12px 32px rgba(0,0,0,.18);
  font-size:0.86rem; line-height:1.4;
}
.jsp-billing-banner[data-notice="ended"]{ border-left-color:var(--accent); }
.jsp-billing-banner-msg{ flex:1; }
.jsp-billing-banner-btn{
  flex:none; border:none; cursor:pointer;
  background:var(--accent); color:#fff;
  border-radius:var(--radius-sm); padding:8px 14px;
  font-size:0.82rem; font-weight:700;
}
.jsp-billing-banner-btn:disabled{ opacity:.6; cursor:default; }
.jsp-billing-banner-close{
  flex:none; border:none; background:none; cursor:pointer;
  color:var(--muted); font-size:1.3rem; line-height:1; padding:0 2px;
}
.jsp-billing-banner{ flex-wrap:wrap; }
.jsp-billing-banner-msg{ flex:1 1 100%; }
.jsp-login-features{
  list-style:none; margin:0; padding:0;
  display:flex; flex-direction:column; gap:26px;
}
.jsp-login-feature{
  display:flex; align-items:center; gap:16px;
  font-size:1rem; color:var(--ink);
}
.jsp-login-feature-icon{
  flex:none;
  width:44px; height:44px;
  display:flex; align-items:center; justify-content:center;
  border-radius:50%;
  border:1px solid var(--line);
  background:#fff;
}
.jsp-login-feature-icon svg{ width:20px; height:20px; }
.jsp-pricing-price .was{ font-size:1.05rem; font-weight:600; color:var(--muted); text-decoration:line-through; margin-right:2px; }
.jsp-pricing-ribbon{
  position:absolute; top:14px; right:14px;
  transform:none;
  background:#111;
  color:#fff;
  font-size:0.68rem; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
  padding:5px 14px; border-radius:100px;
}
.jsp-login-right-brand{
  display:inline-flex; align-items:center; gap:10px;
  align-self:flex-start;
  margin-bottom:36px;
  background:#fff;
  border:1px solid var(--line);
  border-radius:var(--radius-tile);
  padding:12px 18px;
  box-shadow:0 4px 12px rgba(18,21,28,.05);
}
.jsp-login-right-brand img{ height:26px; width:auto; }
.jsp-login-right-brand img.is-wordmark{ height:auto; width:110px; }
.jsp-login-right-brand span{ font-weight:800; font-size:0.85rem; color:var(--ink); }
.jsp-pricing-save{
  display:inline-block; margin-left:6px;
  background:rgba(22,163,74,.14); color:var(--good);
  font-size:0.68rem; font-weight:800; letter-spacing:.02em;
  padding:2px 7px; border-radius:100px;
}
.jsp-pricing-toggle-btn.active .jsp-pricing-save{ background:rgba(255,255,255,.22); color:#fff; }
/* Popular badge stays inside the card; original price struck through. */
.jsp-pricing-card{ overflow:hidden; }
.jsp-pricing-price .was{ text-decoration:line-through; color:#8a8f98; font-size:1rem; font-weight:500; margin-right:8px; }

/* Desktop topbar brand guard (Rankare wordmark + custom logos): never
   exceed the bar. Port dropped the old desktop sizing rule while the
   mobile crop below stays untouched. */
@media (min-width:821px){
  .jsp-topbar-brand-logo{ height:28px; width:auto; max-width:150px; object-fit:contain; }
  .jsp-topbar-brand-logo.is-wordmark{ height:auto; width:140px; max-width:150px; }
}
