/* ============================================================
   ezpztrader.com — dashboard/app shell
   A collapsed icon rail that expands into a full labeled panel
   on hover/focus (smooth width transition, overlays content —
   nothing reflows), with a darker animated ambient-glow
   background instead of a flat panel color. Built on the site's
   existing motion/effects tokens (--ramp, .glow-border, ease
   tokens). Loaded only on dashboard pages.
   ============================================================ */

.dashboard-shell { min-height: 100vh; background: var(--bg); }

.dashboard-rail {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 76px;
  z-index: 80;
  overflow: hidden;
  background:
    radial-gradient(140% 55% at 15% 0%, var(--accent-soft), transparent 60%),
    radial-gradient(120% 50% at 85% 100%, var(--gold-soft), transparent 55%),
    var(--bg-sunken);
  border-right: 1px solid var(--line);
  box-shadow: var(--shadow-1);
  transition: width .35s var(--ease-out), box-shadow .35s var(--ease-out);
}
.dashboard-rail:hover,
.dashboard-rail:has(:focus-visible) {
  width: 240px;
  box-shadow: var(--shadow-2);
}

/* ambient drifting glow, confined to the rail by its overflow:hidden */
.dashboard-rail::before,
.dashboard-rail::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(46px);
  pointer-events: none;
  z-index: 0;
}
.dashboard-rail::before {
  width: 170px; height: 170px;
  left: -70px; top: 6%;
  background: radial-gradient(circle, var(--accent) 0%, transparent 70%);
  opacity: .32;
  animation: rail-drift-a 17s var(--ease-in-out) infinite;
}
.dashboard-rail::after {
  width: 150px; height: 150px;
  left: -60px; bottom: 10%;
  background: radial-gradient(circle, var(--gold) 0%, transparent 70%);
  opacity: .22;
  animation: rail-drift-b 21s var(--ease-in-out) infinite;
}
@keyframes rail-drift-a {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50%      { transform: translate(34px, 22px) scale(1.18); }
}
@keyframes rail-drift-b {
  0%, 100% { transform: translate(0, 0) scale(1.05); }
  50%      { transform: translate(28px, -16px) scale(.88); }
}

.rail-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 1.25rem 0;
}

/* ---------- brand row ---------- */

.rail-brand-row {
  position: relative;
  display: block;
  height: 52px;
  margin: 0 .9rem 1.75rem;
  border-radius: var(--radius-md);
  overflow: hidden;
  flex-shrink: 0;
  transition: height .35s var(--ease-out);
}
.dashboard-rail:hover .rail-brand-row,
.dashboard-rail:has(:focus-visible) .rail-brand-row {
  height: 108px;
}
.rail-brand-icon {
  position: absolute;
  left: .65rem;
  top: 50%;
  transform: translateY(-50%);
  width: 34px; height: 34px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  transition: opacity .2s var(--ease-out);
}
.rail-brand-icon img { width: 100%; height: 100%; object-fit: cover; }

/* full theme-aware wordmark (partials/logo_mark.html), shown big and
   centered once the rail is expanded instead of the small square icon */
.rail-brand-full {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s var(--ease-out) .05s;
}
.rail-brand-full .logo-mark { height: 38px; width: auto; }

.dashboard-rail:hover .rail-brand-icon,
.dashboard-rail:has(:focus-visible) .rail-brand-icon {
  opacity: 0;
}
.dashboard-rail:hover .rail-brand-full,
.dashboard-rail:has(:focus-visible) .rail-brand-full {
  opacity: 1;
  pointer-events: auto;
}

/* ---------- nav rows ---------- */

/* flex:1/min-height:0 lets this scroll independently instead of overflowing
   past .dashboard-rail's overflow:hidden bottom edge — without it, enough
   rail items (or the +56px .rail-brand-row grows on hover) silently pushes
   .rail-footer's last rows (avatar/Log out) off-screen with no way back. */
.rail-nav {
  display: flex; flex-direction: column; gap: .3rem; padding: 0 .9rem;
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  scrollbar-width: none; -ms-overflow-style: none;
}
.rail-nav::-webkit-scrollbar { display: none; }
.rail-footer {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  padding: .9rem .9rem 0;
  margin-top: auto;
  flex-shrink: 0;
  border-top: 1px solid var(--line-soft);
}

.rail-item { position: relative; }
.rail-item form { display: contents; }

.rail-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: .9rem;
  width: 100%;
  height: 44px;
  padding: 0 .65rem;
  border-radius: var(--radius-md);
  overflow: hidden;
  color: var(--ink-soft);
  background: transparent;
  border: none;
  cursor: pointer;
  transition: background-color .25s var(--ease-out), color .25s var(--ease-out);
}
.rail-link:hover, .rail-link:focus-visible { background: var(--bg-elevated); color: var(--ink); }

.rail-link-icon { width: 1.2rem; height: 1.2rem; flex-shrink: 0; display: flex; }
.rail-link-icon svg { width: 100%; height: 100%; }

.rail-label {
  font-weight: 600;
  font-size: .9rem;
  white-space: nowrap;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity .25s var(--ease-out) .05s, transform .25s var(--ease-out) .05s;
}
.dashboard-rail:hover .rail-label,
.dashboard-rail:has(:focus-visible) .rail-label {
  opacity: 1;
  transform: none;
}

.rail-link.is-active { background: var(--accent-soft); color: var(--accent-ink); }
.rail-link.is-active::before {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 20px;
  border-radius: var(--radius-pill);
  background: var(--ramp);
  box-shadow: 0 0 10px 1px var(--accent-glow);
  animation: rail-pulse 2.4s ease-in-out infinite;
}
@keyframes rail-pulse {
  0%, 100% { opacity: .7; }
  50%      { opacity: 1; }
}

.rail-avatar {
  width: 28px; height: 28px;
  flex-shrink: 0;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: .84rem;
  color: var(--accent-ink);
  background: var(--accent-soft);
}
.rail-label-user { color: var(--ink-soft); font-weight: 500; }

.dashboard-main { margin-left: 76px; min-height: 100vh; display: flex; flex-direction: column; }

.dashboard-topbar {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem clamp(1rem, 3vw, 1.5rem);
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(14px) saturate(160%);
  border-bottom: 1px solid var(--line);
}
.dashboard-topbar .logo-mark { height: 38px; }

.dashboard-content { flex: 1; padding: clamp(1.5rem, 3vw, 2.5rem); }

/* The journal assistant is a full-bleed chat layout: only its own chat
   thread and chat-history list should scroll, never the dashboard page
   itself. Scoped via :has() so it doesn't touch any other dashboard page. */
.dashboard-main:has(.ja-full-page) { height: 100vh; overflow: hidden; }
.dashboard-content:has(> .ja-full-page) { padding: 0; overflow: hidden; min-height: 0; }

/* ============ empty state (dashboard, no broker connected) ============ */

.dashboard-empty {
  position: relative;
  min-height: 50vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 1rem;
  padding: 2rem 1rem;
}
.dashboard-empty p { max-width: 44ch; color: var(--ink-soft); }

/* ============ coming soon (temporary site-wide gate) ============ */

.coming-soon-hero {
  position: relative;
  min-height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.coming-soon-badge {
  width: 4.5rem;
  height: 4.5rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  color: var(--accent-ink);
}
.coming-soon-badge.glow-border::after { animation-duration: 4s; }

.coming-soon-hero h1 { font-size: clamp(2.2rem, 5vw, 3.2rem); }

/* ============ onboarding checklist ============ */

.onboarding-checklist { margin: 2rem 0; padding: 1.75rem clamp(1.25rem, 4vw, 2rem); }

.onboarding-checklist-head h2 { margin: .2rem 0 .3rem; font-size: 1.3rem; }
.onboarding-checklist-lede { color: var(--ink-soft); margin-bottom: 0; }

.onboarding-progress-track {
  height: 6px;
  border-radius: 999px;
  background: var(--bg-sunken);
  overflow: hidden;
  margin: 1.25rem 0 1.75rem;
}
.onboarding-progress-bar {
  height: 100%;
  border-radius: 999px;
  background: var(--ramp);
  transition: width .6s var(--ease-out);
}

.onboarding-steps { list-style: none; margin: 0; padding: 0; }

.onboarding-step { position: relative; padding-bottom: 1.5rem; }
.onboarding-step:last-child { padding-bottom: 0; }
.onboarding-step:not(:last-child)::after {
  content: "";
  position: absolute;
  left: 1.24rem;
  top: 2.5rem;
  bottom: 0;
  width: 2px;
  background: var(--line);
}
.onboarding-step.is-complete:not(:last-child)::after { background: var(--buy); }

.onboarding-step-link {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: .5rem;
  margin: -.5rem;
  border-radius: var(--radius-md);
  transition: background .25s var(--ease-out);
}
.onboarding-step-link:hover { background: var(--bg-elevated); }
.onboarding-step-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.onboarding-step-node {
  position: relative;
  z-index: 1;
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-elevated);
  border: 2px solid var(--line);
  color: var(--ink-faint);
}
.onboarding-step-number {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: .95rem;
}
.onboarding-step.is-current .onboarding-step-node {
  border-color: var(--accent);
  color: var(--accent-ink);
  box-shadow: var(--shadow-glow);
  animation: rail-pulse 2s ease-in-out infinite;
}
.onboarding-step.is-complete .onboarding-step-node {
  background: var(--buy);
  border-color: transparent;
  color: var(--bg);
}

.onboarding-step-body { flex: 1; min-width: 0; padding-top: .1rem; }
.onboarding-step-title-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .6rem .75rem;
}
.onboarding-step-title { font-family: var(--font-display); font-weight: 600; }
.onboarding-step-description { display: block; color: var(--ink-soft); font-size: .92rem; margin-top: .2rem; }

.onboarding-step-cta {
  display: none;
  align-items: center;
  gap: .3rem;
  flex-shrink: 0;
  align-self: center;
  font-size: .85rem;
  font-weight: 600;
  color: var(--accent-ink);
  white-space: nowrap;
}
.onboarding-step-link:hover .onboarding-step-cta,
.onboarding-step-link:focus-visible .onboarding-step-cta { color: var(--accent-ink); }

@media (min-width: 640px) {
  .onboarding-step-cta { display: flex; }
}

/* ============ dashboard broker cards ============ */

.dashboard-header-row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.25rem;
  flex-wrap: wrap;
}
.dashboard-header-row .auth-lede { margin-bottom: 0; }

.broker-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1.25rem;
  margin: 2rem 0 1.25rem;
}
.broker-card { display: flex; flex-direction: column; gap: 1.1rem; }
.broker-card-top { display: flex; align-items: center; gap: .85rem; }
.broker-card-title { flex: 1; min-width: 0; }
.broker-card-title h3 { margin: 0 0 .4rem; font-size: 1.05rem; }
.broker-card-balance { display: flex; flex-direction: column; gap: .3rem; }
.broker-card-stats { gap: 1.25rem; font-size: .88rem; color: var(--ink-soft); }

/* ============ broker marketplace ============ */

.market-head { margin-bottom: 2rem; }
.market-head .auth-lede { margin: .5rem 0 0; }

.market-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1.75rem;
}
.market-search {
  position: relative;
  flex: 1;
  min-width: 220px;
  max-width: 340px;
}
.market-search svg {
  position: absolute;
  left: .9rem; top: 50%;
  transform: translateY(-50%);
  width: 1rem; height: 1rem;
  color: var(--ink-faint);
  pointer-events: none;
}
.market-search input {
  width: 100%;
  padding: .7rem 1rem .7rem 2.5rem;
  font-family: var(--font-body);
  font-size: .9rem;
  color: var(--ink);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  transition: border-color .2s var(--ease-out), box-shadow .2s var(--ease-out);
}
.market-search input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.market-filters { display: flex; flex-wrap: wrap; gap: .5rem; }
.market-filter {
  padding: .5rem 1rem;
  font-family: var(--font-body);
  font-size: .88rem;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color .2s var(--ease-out), color .2s var(--ease-out), border-color .2s var(--ease-out);
}
.market-filter:hover { border-color: var(--accent); color: var(--ink); }
.market-filter.is-active {
  background: var(--ramp);
  border-color: transparent;
  color: var(--on-accent);
  box-shadow: 0 6px 18px -8px var(--accent-glow);
}

.market-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1.25rem;
}
.market-card { display: flex; flex-direction: column; gap: .65rem; }
.market-card[hidden] { display: none; }
.market-card-top { display: flex; align-items: center; gap: .75rem; }
.market-card-title { display: flex; align-items: center; gap: .5rem; flex: 1; }
.market-card-title h3 { margin: 0; font-size: 1.05rem; }
.market-card p { color: var(--ink-soft); font-size: .88rem; margin: 0; flex: 1; }
.market-tags { gap: .4rem; }
.market-cta { align-self: flex-start; margin-top: .25rem; }
.market-soon {
  align-self: flex-start;
  margin-top: .25rem;
  background: var(--bg-elevated);
  color: var(--ink-faint);
  border-color: var(--line);
}
.market-empty { text-align: center; color: var(--ink-soft); padding: 3rem 1rem; }

.market-logo {
  width: 2.25rem; height: 2.25rem;
  border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  overflow: hidden;
  flex-shrink: 0;
}
.market-logo img { width: 100%; height: 100%; object-fit: contain; padding: .2rem; }
.market-mono { font-family: var(--font-display); font-weight: 800; font-size: .86rem; letter-spacing: -0.02em; }
.market-logo.badge-violet  { background: var(--accent-soft); border-color: transparent; }
.market-logo.badge-violet  .market-mono { color: var(--accent-ink); }
.market-logo.badge-magenta { background: var(--magenta-soft); border-color: transparent; }
.market-logo.badge-magenta .market-mono { color: var(--magenta); }
.market-logo.badge-gold    { background: var(--gold-soft); border-color: transparent; }
.market-logo.badge-gold    .market-mono { color: var(--gold-ink); }
.market-logo.badge-teal    { background: var(--buy-soft); border-color: transparent; }
.market-logo.badge-teal    .market-mono { color: var(--buy); }
.market-logo.badge-blue    { background: var(--tile-blue-soft); border-color: transparent; }
.market-logo.badge-blue    .market-mono { color: var(--tile-blue); }
.market-logo.badge-rose    { background: var(--sell-soft); border-color: transparent; }
.market-logo.badge-rose    .market-mono { color: var(--sell); }

/* ============ broker detail ============ */

.broker-detail-head {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  max-width: 45rem;
  margin: 1.5rem auto 1.5rem;
}
.broker-detail-head .market-logo { width: 3rem; height: 3rem; }
.broker-detail-summary { color: var(--ink-soft); margin: 0 0 .5rem; }
/* 45rem == 72ch measured against the site's actual font (Manrope, 16px
   root) — kept as a fixed rem value rather than ch on purpose: ch scales
   with each element's own font-size, so mixing ch-based widths across
   elements with different font-sizes (e.g. broker-detail-signup's .92rem
   vs the default) made their edges drift out of alignment even at "the
   same" ch value. rem is always relative to the root font-size, so every
   piece below lines up exactly regardless of its own font-size. */
.broker-detail-description { color: var(--ink-soft); max-width: 45rem; margin: 0 auto .75rem; line-height: 1.6; }
.broker-detail-signup { max-width: 45rem; margin: 0 auto 1.5rem; font-size: .92rem; color: var(--ink-soft); }

.risk-card { margin: 0 auto 1.5rem; max-width: 45rem; }
.risk-card h3 { margin-bottom: .6rem; }
.risk-card p { margin: 0; color: var(--ink-soft); font-size: .92rem; }

.oauth-authorize-card p { font-size: 1rem; line-height: 1.6; }
.oauth-authorize-card strong { color: var(--ink); }
.oauth-authorize-actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.5rem; }

.broker-connect-notice { max-width: 45rem; margin: 0 auto; color: var(--ink-soft); }
.broker-connect-notice p { margin: 0; }

.broker-connect-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.25rem;
  max-width: 45rem;
  margin: 0 auto;
}
.broker-connect-option { display: flex; flex-direction: column; gap: .75rem; }
.broker-connect-option h3 { margin: 0; }
.broker-connect-option p { margin: 0; color: var(--ink-soft); font-size: .88rem; }
.broker-connect-option .btn { align-self: flex-start; }
.broker-connect-option > form { display: contents; }
.broker-limit-note { font-size: .85rem; color: var(--ink-faint); }
.broker-limit-note a { display: block; width: fit-content; margin-top: .6rem; }

.broker-connect-or {
  margin: .25rem 0 0;
  font-size: .86rem;
  color: var(--ink-faint);
}
.broker-apikey-form { width: 100%; }
.broker-apikey-form .form-field { margin-bottom: .75rem; }
.broker-apikey-form .form-field label { font-size: .84rem; margin-bottom: .3rem; }
.broker-apikey-form .form-field input { padding: .6rem .8rem; font-size: .88rem; }

/* ============ connection settings ============ */

.settings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.25rem;
  max-width: 62rem;
}
.settings-card { display: flex; flex-direction: column; gap: 1rem; }
.settings-card h3 { margin: 0; }

.settings-balance-row { display: flex; flex-wrap: wrap; gap: 1.25rem 2rem; }
.settings-balance-row > div { min-width: 8rem; }
.settings-balance-label { display: block; font-size: .84rem; color: var(--ink-faint); margin-bottom: .3rem; }
.settings-balance-value {
  display: block;
  font-family: var(--font-mono);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.settings-synced { margin: 0; font-size: .86rem; color: var(--ink-faint); }

.settings-actions { display: flex; flex-wrap: wrap; gap: .6rem; }
.settings-disconnect:hover { border-color: var(--sell); color: var(--sell); background: var(--sell-soft); }

.settings-rename-form .form-field { margin-bottom: .75rem; }
.settings-rename-form .form-field label { font-size: .84rem; margin-bottom: .3rem; }
.settings-rename-form .form-field input { padding: .6rem .8rem; font-size: .88rem; }

/* ============ broker dashboard ============ */

.broker-dash-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.broker-dash-head h1 { margin: 0; }
.broker-dash-head-title { display: flex; align-items: center; gap: 1rem; min-width: 0; }
.broker-dash-head-title .market-logo { width: 2.75rem; height: 2.75rem; flex-shrink: 0; }

.broker-dash-balances {
  display: flex;
  flex-wrap: wrap;
  gap: 2.5rem;
  padding: 1.5rem 0;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--line);
}
.settings-balance-value-sm { font-size: .95rem; font-weight: 500; }

.broker-dash-section { margin-bottom: 2.5rem; }
.broker-dash-section h2 { font-size: 1.1rem; margin-bottom: 1rem; }
.broker-dash-empty { color: var(--ink-soft); font-size: .9rem; }

/* ============ strategies: shared hero/badge/step components ============ */

.strategy-hero {
  position: relative;
  padding: 1.75rem 2rem;
  margin-bottom: 1.75rem;
  border-radius: var(--radius-lg);
  border: 1px solid var(--line);
  background:
    radial-gradient(ellipse 60% 100% at 12% 0%, var(--accent-soft) 0%, transparent 60%),
    radial-gradient(ellipse 50% 90% at 95% 100%, var(--gold-soft) 0%, transparent 55%),
    var(--bg-raised);
}
.strategy-hero .dashboard-header-row { gap: 1.25rem; }
.strategy-hero h1 { margin: .6rem 0 .5rem; }

.strategy-asset-badge {
  width: 2.5rem; height: 2.5rem;
  border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.strategy-asset-badge svg { width: 1.15rem; height: 1.15rem; }
.strategy-asset-badge.badge-lg { width: 3.5rem; height: 3.5rem; border-radius: var(--radius-md); }
.strategy-asset-badge.badge-lg svg { width: 1.75rem; height: 1.75rem; }
.strategy-asset-badge.badge-stocks  { background: var(--tile-blue-soft); color: var(--tile-blue); }
.strategy-asset-badge.badge-options { background: var(--accent-soft); color: var(--accent-ink); }
.strategy-asset-badge.badge-futures { background: var(--gold-soft); color: var(--gold-ink); }
.strategy-asset-badge.badge-crypto  { background: var(--magenta-soft); color: var(--magenta); }

.strategy-step-badge {
  position: relative;
  flex-shrink: 0;
  width: 2.25rem; height: 2.25rem;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: .95rem;
  color: var(--accent-ink);
  background: var(--accent-soft);
}
.strategy-section-head { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: 1.25rem; }
/* Without this, the text column's default flex min-width:auto keeps it
   at its unwrapped intrinsic width, overflowing past the card edge in
   narrower contexts (e.g. the Security page's multi-column grid). */
.strategy-section-head > div { min-width: 0; }
/* "Two-factor authentication" is longer than any heading this component
   previously carried — "authentication" alone can be wider than a narrow
   grid column at this display font-size, and a single word doesn't get a
   natural wrap point without this. */
/* Card sub-heading, not a page heading — without this it inherits the
   giant page-level h2 clamp() and "Two-factor authentication" overflows
   a narrow grid column even with the wrap fix above. Previously only
   looked right because every prior use happened to also sit inside
   .strategy-form-section, which already sets this same size. */
.strategy-section-head h2 { margin: 0 0 .3rem; font-size: 1.1rem; overflow-wrap: break-word; }
.strategy-section-head .settings-synced { margin: 0; }

.broker-dash-section-head { display: flex; align-items: center; gap: .75rem; margin-bottom: 1rem; }
.broker-dash-section-head h2 { margin: 0; }

/* ============ strategies list: toolbar + collapsible filter drawer ============
   Deliberately not a static, always-visible left sidebar — a top search
   bar, a toggleable "Filters" drawer, and removable chips for whatever's
   active, closer to a modern command-bar pattern than an always-visible
   admin panel. */

.strategy-toolbar {
  display: flex;
  align-items: center;
  gap: .85rem;
  margin-bottom: 1.25rem;
}
.strategy-search { flex: 1; max-width: 420px; margin: 0; }

.strategy-filters-toggle { position: relative; display: inline-flex; align-items: center; gap: .5rem; }
.strategy-filters-toggle svg { width: 1rem; height: 1rem; }
.strategy-filter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.1rem;
  height: 1.1rem;
  padding: 0 .3rem;
  border-radius: var(--radius-pill);
  background: var(--ramp);
  color: #fff;
  font-size: .74rem;
  font-weight: 700;
}

.strategy-clear-all {
  font-size: .88rem;
  color: var(--ink-faint);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.strategy-clear-all:hover { color: var(--sell); }

.strategy-filter-drawer { margin-bottom: 1.25rem; }
.strategy-filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1.25rem 1.5rem;
}
.strategy-filter-drawer .form-field { margin-bottom: 0; }
.strategy-filter-drawer .form-field input { padding: .6rem .8rem; font-size: .88rem; }
.strategy-filter-drawer .seg-group { gap: .4rem; }
.strategy-filter-drawer .seg-option { padding: .38rem .75rem; font-size: .82rem; }
.strategy-filter-actions { display: flex; gap: .6rem; margin-top: 1.25rem; }

.strategy-chip-row { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.25rem; }
.strategy-chip {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .75rem;
  font-size: .84rem;
  font-weight: 600;
  color: var(--accent-ink);
  background: var(--ramp-soft);
  border-radius: var(--radius-pill);
  transition: background-color .2s var(--ease-out);
}
.strategy-chip:hover { background: var(--sell-soft); color: var(--sell); }
.strategy-chip span { font-size: .95rem; line-height: 1; }

.strategy-results { min-width: 0; }
.strategy-list { display: flex; flex-direction: column; gap: 1rem; }
.strategy-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  border-left: 3px solid var(--line);
  transition: border-color .2s var(--ease-out);
}
.strategy-row.is-enabled { border-left-color: var(--buy); }
/* Whole-card "stretched link" to Edit — placed first among .card-hover's
   children so it shares their z-index:1 (see .card-hover > * above) but
   paints beneath every later sibling (checkbox, main content, action
   buttons/links), which therefore still intercept clicks on themselves
   normally. Only the card's empty background area falls through to this. */
.strategy-row-link { position: absolute; inset: 0; }
/* Nothing inside .strategy-row-main (badge, name, summary, pills) is
   itself interactive — without pointer-events:none it still sits above
   the stretched link (.card-hover > * gives every direct child z-index:1)
   and silently swallows clicks with no effect, so only the empty padding
   around it actually opened Edit. This lets clicks fall through the whole
   content block to the link beneath. */
.strategy-row-main { display: flex; align-items: flex-start; gap: 1rem; min-width: 0; flex: 1; pointer-events: none; }
.strategy-row-info { min-width: 0; }
.strategy-row-info h3 { margin: 0 0 .3rem; font-size: 1.05rem; }
.strategy-row-summary { margin: 0 0 .6rem; font-size: .85rem; color: var(--ink-soft); }
.strategy-row-pills { gap: .4rem; }
.strategy-row-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.strategy-delete:hover { border-color: var(--sell); color: var(--sell); background: var(--sell-soft); }

.mono { font-family: var(--font-mono); }

/* ============ strategy bulk select ============ */

.strategy-row-checkbox-wrap { display: flex; align-items: center; padding-top: .2rem; }
.strategy-row-checkbox-wrap input { width: 1.05rem; height: 1.05rem; accent-color: var(--accent); cursor: pointer; }

.strategy-list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: .75rem;
  margin-bottom: 1rem;
}
.strategy-select-all {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: .85rem;
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
}
.strategy-select-all input { width: 1.05rem; height: 1.05rem; accent-color: var(--accent); cursor: pointer; }

.strategy-bulk-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .6rem;
  padding: .4rem .6rem .4rem 1rem;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
}
/* Author-origin display:flex above ties in specificity with the browser's
   own [hidden]{display:none} and wins by cascade origin — same bug already
   hit and fixed once for .market-card[hidden] in the broker marketplace. */
.strategy-bulk-actions[hidden] { display: none; }
.strategy-bulk-count { font-size: .86rem; font-weight: 700; color: var(--accent-ink); white-space: nowrap; }

/* ============ subscriptions list: toolbar + filter drawer ============
   Same command-bar pattern as the strategies list (.strategy-toolbar etc.)
   — a parallel, feature-prefixed block rather than a shared abstraction,
   matching how .market-* (brokers) and .strategy-* already coexist here
   without a shared base. Row actions (New Subscription, Dashboard/Trades/
   Edit, Enable/Disable/Delete) are disabled placeholders this slice —
   SUBSCRIPTIONS.md §4 Slice 1 is read-only list + filters only, so there's
   no bulk-select bar yet either (nothing for it to trigger until Slice 7). */

.subscription-toolbar { display: flex; align-items: center; gap: .85rem; margin-bottom: 1.25rem; }
.subscription-search { flex: 1; max-width: 420px; margin: 0; }

.subscription-filters-toggle { position: relative; display: inline-flex; align-items: center; gap: .5rem; }
.subscription-filters-toggle svg { width: 1rem; height: 1rem; }
.subscription-filter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.1rem;
  height: 1.1rem;
  padding: 0 .3rem;
  border-radius: var(--radius-pill);
  background: var(--ramp);
  color: #fff;
  font-size: .74rem;
  font-weight: 700;
}

.subscription-clear-all { font-size: .88rem; color: var(--ink-faint); text-decoration: underline; text-underline-offset: 3px; }
.subscription-clear-all:hover { color: var(--sell); }

.subscription-filter-drawer { margin-bottom: 1.25rem; }
.subscription-filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1.25rem 1.5rem;
}
.subscription-filter-drawer .form-field { margin-bottom: 0; }
.subscription-filter-drawer .form-field input,
.subscription-filter-drawer .form-field select { padding: .6rem .8rem; font-size: .88rem; }
.subscription-filter-drawer .seg-group { gap: .4rem; }
.subscription-filter-drawer .seg-option { padding: .38rem .75rem; font-size: .82rem; }
.subscription-filter-actions { display: flex; gap: .6rem; margin-top: 1.25rem; }

.subscription-chip-row { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 1.25rem; }
.subscription-chip {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .75rem;
  font-size: .84rem;
  font-weight: 600;
  color: var(--accent-ink);
  background: var(--ramp-soft);
  border-radius: var(--radius-pill);
  transition: background-color .2s var(--ease-out);
}
.subscription-chip:hover { background: var(--sell-soft); color: var(--sell); }
.subscription-chip span { font-size: .95rem; line-height: 1; }

.subscription-results { min-width: 0; }
.subscription-list { display: flex; flex-direction: column; gap: 1rem; }
.subscription-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  border-left: 3px solid var(--line);
  transition: border-color .2s var(--ease-out);
}
.subscription-row.is-enabled { border-left-color: var(--buy); }
.subscription-row-main { display: flex; align-items: flex-start; gap: 1rem; min-width: 0; flex: 1; }
.subscription-row-info { min-width: 0; }
.subscription-row-info h3 { margin: 0 0 .3rem; font-size: 1.05rem; }
.subscription-row-summary { margin: 0 0 .6rem; font-size: .85rem; color: var(--ink-soft); }
.subscription-row-pills { gap: .4rem; }
.subscription-row-actions { display: flex; flex-wrap: wrap; gap: .5rem; }

/* ============ subscription create wizard (3-step: strategy/account/confirm) ============ */

.wizard-progress { display: flex; gap: .5rem; margin: 1.25rem 0 1.5rem; }
.wizard-progress-seg { flex: 1; height: .35rem; border-radius: var(--radius-pill); background: var(--line); transition: background-color .2s var(--ease-out); }
.wizard-progress-seg.is-done { background: var(--accent); }

.wizard-card { padding: 1.75rem; }

.wizard-step-head { display: flex; align-items: center; gap: .75rem; margin-bottom: 1.5rem; }
.wizard-step-head svg { width: 1.3rem; height: 1.3rem; color: var(--accent-ink); flex-shrink: 0; }
.wizard-step-head h2 { margin: 0; font-size: .95rem; letter-spacing: .04em; text-transform: uppercase; color: var(--ink); }

.wizard-controls { display: flex; align-items: center; flex-wrap: wrap; gap: .85rem; margin-bottom: 1.5rem; }
.wizard-search { flex: 1; min-width: 220px; max-width: 420px; margin: 0; }

.wizard-picker-list { display: flex; flex-direction: column; gap: .85rem; }
.wizard-picker-row { display: flex; align-items: center; gap: 1rem; text-decoration: none; color: inherit; }
.wizard-picker-row:hover { border-color: var(--accent); }
.wizard-picker-info { min-width: 0; flex: 1; }
.wizard-picker-info h3 { margin: 0 0 .3rem; font-size: 1.02rem; }
.wizard-picker-summary { margin: 0; font-size: .85rem; color: var(--ink-soft); }
.wizard-picker-pills { gap: .4rem; margin-top: .5rem; }

.wizard-empty { text-align: center; color: var(--ink-soft); padding: 2.5rem 1rem; }
.wizard-empty p { max-width: 44ch; margin: 0 auto 1rem; }

.wizard-summary-table { display: flex; flex-direction: column; margin-bottom: 1.25rem; }
.wizard-summary-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: .9rem 0; border-bottom: 1px solid var(--line); }
.wizard-summary-row:last-child { border-bottom: none; }
.wizard-summary-label { font-weight: 600; color: var(--ink-soft); font-size: .85rem; }
.wizard-summary-value { font-size: .92rem; text-align: right; }
.wizard-confirm-note { color: var(--ink-soft); font-size: .9rem; margin-bottom: 1.5rem; }

.wizard-actions { display: flex; gap: .75rem; margin-top: 1.25rem; }

/* ============ strategy form ============ */

.strategy-form { display: flex; flex-direction: column; gap: 1.5rem; margin-top: 1.5rem; }
.strategy-form-section h2 { margin: 0 0 .3rem; font-size: 1.1rem; }
.strategy-form-section > p.settings-synced { margin-bottom: 1.25rem; }
/* Full-width cards, but individual text fields stay readable rather than
   stretching edge-to-edge on a wide screen. */
.strategy-form-section .form-field input[type="text"],
.strategy-form-section .form-field textarea,
.strategy-form-section .form-field input[type="search"] {
  max-width: 640px;
}

.strategy-form textarea {
  width: 100%;
  padding: .8rem 1rem;
  font-family: var(--font-body);
  font-size: .95rem;
  color: var(--ink);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  resize: vertical;
  transition: border-color .2s var(--ease-out), box-shadow .2s var(--ease-out);
}
.strategy-form textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.seg-group { display: flex; flex-wrap: wrap; gap: .5rem; }
.seg-option {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: .5rem 1rem;
  font-size: .88rem;
  font-weight: 600;
  color: var(--ink-soft);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: background-color .2s var(--ease-out), color .2s var(--ease-out), border-color .2s var(--ease-out);
}
.seg-option:hover { border-color: var(--accent); color: var(--ink); }
.seg-option input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.seg-option:has(input:checked) {
  background: var(--ramp);
  border-color: transparent;
  color: var(--on-accent);
  box-shadow: 0 4px 16px -4px var(--accent-glow);
}
.seg-option:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

.radio-group { display: flex; flex-direction: column; gap: .6rem; }
.radio-option, .checkbox-option {
  display: flex;
  align-items: center;
  gap: .6rem;
  font-size: .9rem;
  color: var(--ink);
  cursor: pointer;
}
.radio-option input, .checkbox-option input { accent-color: var(--accent); width: 1rem; height: 1rem; flex-shrink: 0; }
.strategy-checkboxes { display: flex; flex-direction: column; gap: .6rem; margin-top: 1.25rem; }

.strategy-conditional { margin-top: .75rem; margin-bottom: 0; }
.strategy-conditional[hidden] { display: none; }

.strategy-form-actions { display: flex; gap: .75rem; }

.subscription-edit-summary { display: flex; align-items: center; gap: 1rem; margin-bottom: .5rem; }
.subscription-edit-summary .auth-lede { margin: 0; }

/* ============ subscription edit form: Trading Window / Entry / Exit extras ============ */

.strategy-subsection-head { margin: 1.75rem 0 1rem; padding-top: 1.25rem; border-top: 1px dashed var(--line); }
.strategy-subsection-head h3 { margin: 0; font-size: .9rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); }

.input-with-seg { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; }
.input-with-seg input { flex: 1; min-width: 140px; }

/* ============ field info icon + modal ============ */
/* One icon per section header (not per field) — click opens a centered
   modal (dialog.modal, same system as the webhook modal: modal.js wires
   [data-modal-trigger]/[data-modal-close]/backdrop-click, native <dialog>
   gives free centering + Escape-to-close + real top-layer stacking that
   no ancestor transform can hijack) listing every field explanation for
   that section. Sits as the last flex child of .strategy-section-head,
   pushed to the row's far right. */

.strategy-section-head > .field-info { margin-left: auto; align-self: center; }

.field-info {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.85rem;
  height: 1.85rem;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--bg-sunken);
  padding: 0;
  cursor: pointer;
  font-size: 0;
  line-height: 0;
  transition: background-color .2s var(--ease-out), border-color .2s var(--ease-out),
    box-shadow .2s var(--ease-out), transform .15s var(--ease-out);
}
.field-info::before {
  content: "";
  display: block;
  width: 1rem;
  height: 1rem;
  background-color: var(--ink-faint);
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='black'%3E%3Cpath fill-rule='evenodd' d='M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z' clip-rule='evenodd'/%3E%3C/svg%3E") center / contain no-repeat;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='black'%3E%3Cpath fill-rule='evenodd' d='M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z' clip-rule='evenodd'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: background-color .2s var(--ease-out);
}
.field-info:hover,
.field-info:focus-visible {
  border-color: transparent;
  background: var(--accent-soft);
  box-shadow: 0 0 0 3px var(--accent-soft), 0 4px 14px -4px var(--accent-glow);
  transform: scale(1.1);
}
.field-info:hover::before,
.field-info:focus-visible::before { background-color: var(--accent-ink); }
.field-info:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

dialog.modal.modal-info {
  width: min(94vw, 460px);
  background:
    radial-gradient(130% 60% at 100% 0%, var(--accent-soft) 0%, transparent 55%),
    var(--bg-raised);
}

.info-list { margin: 0; }
.info-list dt {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: .01em;
  color: var(--ink);
}
.info-list dt::before {
  content: "";
  width: .4rem;
  height: .4rem;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 6px 1px var(--accent-glow);
}
.info-list dt:not(:first-child) {
  margin-top: .9rem;
  padding-top: .9rem;
  border-top: 1px dashed var(--line);
}
.info-list dd { margin: .3rem 0 0 .9rem; color: var(--ink-soft); }
.info-list dd .opt { display: block; }
.info-list dd .opt + .opt { margin-top: .5rem; }

.trading-window-list { display: flex; flex-direction: column; gap: .75rem; margin-bottom: .85rem; }
.trading-window-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  padding: .85rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-sunken);
}
.trading-window-days { display: flex; flex-wrap: wrap; gap: .6rem; }
.checkbox-option-compact { gap: .3rem; font-size: .86rem; }
.trading-window-times { display: flex; align-items: center; gap: .5rem; }
.trading-window-times input { width: auto; padding: .5rem .6rem; }

/* ============ strategy detail nav + status bar ============ */

.strategy-detail-nav { display: flex; flex-wrap: wrap; gap: .5rem; }
.strategy-status-bar { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: 1rem 0 1.75rem; }
.strategy-status-bar button { display: inline-flex; align-items: center; gap: .45rem; }
.strategy-status-bar button svg { width: .95rem; height: .95rem; }
.strategy-status-form { display: contents; }

/* Enabled/Disabled and Auto/Manual Submit render as real <button>s so they
   double as toggles, styled to still read as pills like the rest of the
   status row rather than looking like a default browser button. */
.pill-btn {
  font-family: inherit;
  cursor: pointer;
  transition: filter .15s var(--ease-out), transform .15s var(--ease-out);
}
.pill-btn:hover { filter: brightness(1.18); }
.pill-btn:active { transform: translateY(1px); }
.pill-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.pill-btn:disabled { opacity: .55; cursor: not-allowed; }
.pill-btn:disabled:hover { filter: none; }
.pill-btn:disabled:active { transform: none; }

/* ============ team access banner (USER_MANAGEMENT.md) ============ */
.team-access-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: .65rem 1.25rem;
  background: var(--accent-soft);
  border-bottom: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: .9rem;
}
.team-access-banner strong { color: var(--ink); }
.team-access-banner a { color: var(--accent-ink); }

.team-member-identity { display: flex; align-items: center; gap: .65rem; }
.team-member-row-actions {
  white-space: nowrap;
  gap: .5rem;
  justify-content: flex-end;
}
.team-member-row-actions form { display: inline-flex; }
.team-member-role-select { min-width: 150px; }

/* ============ webhook modal ============ */

dialog.modal {
  /* Without this, Chromium centers a modal dialog via position:absolute
     against document coordinates captured at open time — on a long page
     that's been scrolled (e.g. opening one of the lower section's info
     modals), that math goes stale and the dialog renders far off-screen.
     position:fixed centers against the live viewport instead, immune to
     scroll position. */
  position: fixed;
  inset: 0;
  margin: auto;
  border: none;
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  color: var(--ink);
  padding: 0;
  width: min(96vw, 1140px);
  max-height: min(88vh, 760px);
  box-shadow: var(--shadow-2);
}
dialog.modal::backdrop { background: rgba(4, 2, 18, .65); backdrop-filter: blur(6px); }

.modal-inner { padding: 1.75rem; max-height: min(88vh, 720px); overflow-y: auto; }
.modal-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: .5rem; }
.modal-header h2 { margin: 0; display: flex; align-items: center; gap: .6rem; font-size: 1.2rem; }
.modal-header h2 svg { width: 1.15rem; height: 1.15rem; color: var(--accent-ink); flex-shrink: 0; }
.modal-close {
  background: none; border: none; color: var(--ink-faint);
  font-size: 1.4rem; line-height: 1; cursor: pointer; padding: .2rem .4rem;
}
.modal-close:hover { color: var(--ink); }
.modal-lede { color: var(--ink-soft); font-size: .9rem; margin: 0 0 1.25rem; }

.webhook-url-row { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; margin-bottom: .6rem; }
.webhook-url-display {
  flex: 1;
  min-width: 200px;
  padding: .7rem .9rem;
  font-family: var(--font-mono);
  font-size: .88rem;
  color: var(--ink);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow-x: auto;
  white-space: nowrap;
}
.webhook-warning {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  font-size: .86rem;
  color: var(--gold-ink);
  margin: 0 0 1.25rem;
}
.webhook-warning svg { width: 1rem; height: 1rem; flex-shrink: 0; margin-top: .1rem; }

.webhook-actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-bottom: 1.75rem; }
.webhook-actions form { display: contents; }

.modal-inner h3 { font-size: .95rem; margin: 0 0 .3rem; }
.webhook-payload-note { font-size: .86rem; color: var(--ink-faint); margin: 0 0 1.1rem; }

.webhook-payload-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 1rem; }

/* ============ confirm modal (replaces native window.confirm — confirm.js) ============ */

dialog.modal-confirm { width: min(92vw, 420px); }
dialog.modal-confirm .modal-inner {
  padding: 2rem 1.75rem 1.75rem;
  max-height: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.modal-confirm-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  margin-bottom: 1rem;
  border-radius: 50%;
  background: var(--gold-soft);
  color: var(--gold-ink);
}
.modal-confirm-icon svg { width: 1.5rem; height: 1.5rem; }
.modal-confirm-message { margin: 0 0 1.5rem; color: var(--ink); font-size: 1rem; line-height: 1.5; }
.modal-confirm-actions { display: flex; gap: .75rem; width: 100%; }
.modal-confirm-actions .btn { flex: 1 1 0; }
.btn-confirm-accept { background: var(--sell); border-color: var(--sell); color: #2B0509; }
.btn-confirm-accept:hover { filter: brightness(1.08); }
.webhook-payload-card {
  padding: 1rem;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  gap: .6rem;
}
.webhook-payload-head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.webhook-payload-label { font-size: .84rem; color: var(--ink-soft); font-weight: 600; }
.webhook-payload-card p { margin: 0; font-size: .86rem; color: var(--ink-faint); }
.webhook-payload-code {
  margin: 0;
  padding: .75rem;
  background: var(--bg-elevated);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: .8rem;
  line-height: 1.5;
  color: var(--ink);
  white-space: pre-wrap;
  word-break: break-all;
}
.webhook-payload-card .btn { align-self: flex-start; }

/* ============ account settings page ============ */

.settings-layout {
  display: grid;
  grid-template-columns: 190px 1fr;
  align-items: start;
  gap: 2.5rem;
  max-width: 78rem;
  margin-top: 1.75rem;
}

/* Section cards stretch to fill the wider layout, but a lone text/select
   field looks odd spanning the whole card — cap those specifically while
   letting the checkbox grids/lists below use the full card width. */
.settings-section-card .form-field:has(> input:not([type="checkbox"]):not([type="radio"])),
.settings-section-card .form-field:has(> select) {
  max-width: 28rem;
}

.settings-page-nav { position: sticky; top: 1.5rem; display: flex; flex-direction: column; gap: .2rem; }
.settings-page-nav-label {
  font-size: .78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--ink-faint);
  margin-bottom: .5rem;
}
.settings-page-nav nav { display: flex; flex-direction: column; gap: .15rem; }
.settings-page-nav a {
  padding: .5rem .7rem;
  border-radius: var(--radius-sm);
  font-size: .85rem;
  font-weight: 500;
  color: var(--ink-soft);
  transition: background-color .2s var(--ease-out), color .2s var(--ease-out);
}
.settings-page-nav a:hover, .settings-page-nav a:focus-visible { background: var(--bg-elevated); color: var(--ink); }

.settings-sections { display: flex; flex-direction: column; gap: 1.75rem; min-width: 0; }
.settings-section-card { scroll-margin-top: 5.5rem; }
.settings-section-card h2 { margin: 0 0 .3rem; }

.settings-setup-banner {
  margin-bottom: 1.5rem;
  padding: .85rem 1.1rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--gold);
  background: color-mix(in srgb, var(--gold) 12%, transparent);
  color: var(--ink);
  font-size: .9rem;
}
.required-marker { color: var(--gold); }

.settings-checkbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: .6rem .75rem;
}

.settings-checkbox-list { display: flex; flex-direction: column; gap: .75rem; }
.settings-checkbox-card {
  display: flex;
  align-items: flex-start;
  gap: .75rem;
  padding: .9rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color .2s var(--ease-out), background-color .2s var(--ease-out);
}
.settings-checkbox-card:hover { border-color: var(--accent); }
.settings-checkbox-card:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.settings-checkbox-card input { margin-top: .2rem; accent-color: var(--accent); width: 1rem; height: 1rem; flex-shrink: 0; }
.settings-checkbox-card strong { display: block; font-size: .9rem; color: var(--ink); }
.settings-checkbox-desc { display: block; font-size: .86rem; color: var(--ink-faint); margin-top: .15rem; }

/* ============ security page ============ */

/* One full-width row per setting, not a multi-column grid — a 4-across
   grid of short cards read as cramped, and each row here has room to lay
   its description on the left and its status/action on the right instead
   of stacking everything and leaving the rest of the card empty. */
.security-rows { display: flex; flex-direction: column; gap: 1.5rem; margin-top: 1.75rem; }
.security-row-main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
}
.security-row-info { display: flex; align-items: flex-start; gap: 1rem; flex: 1 1 320px; min-width: 0; }
.security-row-info p { margin: 0; }
.security-row-action { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.security-row-extra { margin: 1.25rem 0 0; padding-top: 1.25rem; border-top: 1px dashed var(--line); }
.security-row-extra-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 1rem; }

/* Backup codes as a filled grid of chips rather than a single tall,
   mostly-empty column now that the card spans the full row. */
.backup-codes-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: .75rem;
}
.backup-code-chip {
  padding: .8rem 1rem;
  text-align: center;
  font-family: var(--font-mono);
  letter-spacing: .05em;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}

/* ============ Fire Panel (COMMAND_PAD.md, renamed from Command Pad 2026-08-25) ============ */

.howto-card { margin-bottom: 1.5rem; }
.howto-list { display: flex; flex-direction: column; gap: 1rem; margin-top: 1rem; }
.howto-step { display: flex; gap: .9rem; align-items: flex-start; }
.howto-step-number {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: .82rem;
  font-weight: 700;
}
.howto-step-title { display: block; font-weight: 600; color: var(--ink); margin-bottom: .15rem; }
.howto-step-desc { display: block; font-size: .88rem; color: var(--ink-faint); }
.form-field-hint { display: block; font-size: .82rem; color: var(--ink-faint); margin-top: .4rem; }

/* Rail nav "needs your attention" count badge — pending approvals */
.rail-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 .4rem;
  margin-left: auto;
  border-radius: var(--radius-pill);
  background: var(--gold);
  color: #241800;
  font-family: var(--font-mono);
  font-size: .74rem;
  font-weight: 700;
  line-height: 1.25rem;
  flex-shrink: 0;
}
/* Collapsed rail (icon-only, not hovered/focused) — float the badge on
   the icon itself instead of after a label that isn't visible yet.
   Matches the rail's own expand trigger (:hover / :has(:focus-visible)),
   not :focus-within — see the rail's own rules above this block. */
.dashboard-rail:not(:hover):not(:has(:focus-visible)) .rail-badge {
  position: absolute;
  top: .1rem;
  left: 1.55rem;
  margin-left: 0;
  min-width: 1.05rem;
  height: 1.05rem;
  font-size: .68rem;
  line-height: 1.05rem;
  padding: 0 .3rem;
}

.fire-panel-actions { display: flex; flex-wrap: wrap; gap: .75rem; }
.fire-panel-actions .btn { flex: 1 1 130px; }
.fire-panel-btn-buy { background: var(--buy); border-color: var(--buy); color: #04241A; }
.fire-panel-btn-buy:hover { filter: brightness(1.08); }
.fire-panel-btn-sell { background: var(--sell); border-color: var(--sell); color: #2B0509; }
.fire-panel-btn-sell:hover { filter: brightness(1.08); }
.settings-checkbox-card.is-disabled { opacity: .55; }
.settings-checkbox-card.is-disabled:hover { border-color: var(--line); background: none; }

/* ============ mobile: rail becomes a fixed-width off-canvas drawer,
   always showing labels (no hover on touch) ============ */

@media (max-width: 900px) {
  .dashboard-rail {
    left: auto;
    right: 0;
    width: min(78vw, 300px) !important;
    transform: translateX(100%);
    transition: transform .32s var(--ease-out);
    box-shadow: none;
  }
  .nav-open .dashboard-rail { transform: translateX(0); }
  .rail-content { padding-bottom: max(1.5rem, env(safe-area-inset-bottom)); overflow-y: auto; }
  .rail-label { opacity: 1 !important; transform: none !important; }
  .rail-brand-row { height: 84px !important; }
  .rail-brand-icon { opacity: 0 !important; }
  .rail-brand-full { opacity: 1 !important; pointer-events: auto !important; }

  .dashboard-main { margin-left: 0; }
  .dashboard-topbar { display: flex; }

  .strategy-hero { padding: 1.25rem 1.25rem; }
  .strategy-toolbar { flex-wrap: wrap; }
  .strategy-search { max-width: none; flex-basis: 100%; }
  .strategy-filter-grid { grid-template-columns: 1fr; }
  .strategy-row { flex-direction: column; align-items: flex-start; }
  .strategy-row-actions { width: 100%; }
  .strategy-row-actions .btn { flex: 1 1 auto; }
  .strategy-bulk-actions { width: 100%; justify-content: space-between; }

  .subscription-row { flex-direction: column; align-items: flex-start; }
  .subscription-row-actions { width: 100%; }
  .subscription-row-actions .btn { flex: 1 1 auto; }

  .modal-inner { padding: 1.25rem; }
  .webhook-payload-grid { grid-template-columns: 1fr; }

  .settings-layout { grid-template-columns: 1fr; gap: 1.5rem; }
  .settings-page-nav { position: static; }
  .settings-page-nav nav { flex-direction: row; flex-wrap: wrap; }
  .settings-checkbox-grid { grid-template-columns: 1fr 1fr; }
}

/* Journal — trade notes/tags/playbook + screenshot editor
   (TRADE_JOURNAL.md), one form/one Save button split across two visual
   columns. .journal-form-col is used on both the actual <form> (notes/
   tags/playbook) and its sibling column (existing screenshots + the
   dropzone, which submit via the form="journal-form" attribute instead
   of physical nesting — see trade_detail.html's comment). */
.journal-form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.75rem 2.5rem;
  max-width: 880px;
  padding: 1.5rem;
}
.journal-form-col { display: flex; flex-direction: column; gap: .9rem; min-width: 0; }
.journal-form-col .form-field { margin-bottom: 0; }
.journal-form-actions {
  grid-column: 1 / -1;
  margin-top: .25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}
.journal-form-col textarea {
  width: 100%;
  padding: .75rem .9rem;
  font-family: var(--font-body);
  font-size: .95rem;
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  resize: vertical;
  transition: border-color .2s var(--ease-out), box-shadow .2s var(--ease-out);
}
.journal-form-col textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.journal-form-col .form-field-hint { margin-top: .3rem; }
@media (max-width: 900px) {
  .journal-form-grid { grid-template-columns: 1fr; gap: 1.25rem; padding: 1.25rem; }
}

/* Removable-chip tag editor — [data-tag-input] wrapper, wired up by
   static/js/tag-input.js. The visible chips are pure UI; the actual
   value the form submits lives in the hidden [data-tag-value] input as
   a plain comma-joined string, same shape views.py's _split_list already
   parses, so no server-side change was needed for this upgrade. */
.tag-input {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem;
  padding: .55rem .65rem;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color .2s var(--ease-out), box-shadow .2s var(--ease-out);
}
.tag-input:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: .3rem .4rem .3rem .65rem;
  background: var(--accent-soft);
  color: var(--accent-ink);
  border-radius: 999px;
  font-size: .82rem;
  font-weight: 600;
  white-space: nowrap;
}
.tag-chip button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15rem;
  height: 1.15rem;
  border: none;
  background: transparent;
  color: inherit;
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  opacity: .65;
  border-radius: 50%;
  transition: opacity .15s var(--ease-out), background .15s var(--ease-out);
}
.tag-chip button:hover { opacity: 1; background: rgba(0, 0, 0, .1); }
/* Two classes so this beats the global .form-field input rule's
   width:100%/border/background (0,1,1 specificity vs this rule's 0,2,0) —
   without it the chip and the text field don't share a row at all. */
.form-field .tag-input-text {
  flex: 1;
  width: auto;
  min-width: 8rem;
  border: none;
  background: transparent;
  padding: .3rem .2rem;
  font-family: var(--font-body);
  font-size: .9rem;
  color: var(--ink);
}
.form-field .tag-input-text:focus { outline: none; box-shadow: none; }
.tag-input-text::placeholder { color: var(--ink-faint); }

/* Journal — screenshot upload dropzone (TRADE_JOURNAL.md), wired by
   static/js/file-dropzone.js. The real <input type="file"> is still
   what submits — this only changes how choosing a file looks/feels. */
.dropzone {
  position: relative;
  border: 1.5px dashed var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-sunken);
  padding: 1.15rem 1rem;
  text-align: center;
  cursor: pointer;
  transition: border-color .2s var(--ease-out), background .2s var(--ease-out);
}
.dropzone:hover, .dropzone:focus-within { border-color: var(--accent); }
.dropzone.is-dragover { border-color: var(--accent); background: var(--accent-soft); }
.dropzone-empty { display: flex; flex-direction: column; align-items: center; gap: .5rem; }
.dropzone-empty svg { color: var(--ink-faint); }
.dropzone-empty p { margin: 0; font-size: .92rem; }
.dropzone-empty .form-field-hint { margin: 0; }
.dropzone-preview { display: flex; align-items: center; gap: 1rem; text-align: left; cursor: default; }
/* Author-origin display:flex above ties in specificity with the browser's
   own [hidden]{display:none} and wins by cascade origin — same bug already
   hit and fixed for .market-card[hidden]/.strategy-bulk-actions[hidden]. */
.dropzone-empty[hidden], .dropzone-preview[hidden] { display: none; }
.dropzone-preview img {
  width: 4.5rem; height: 4.5rem; object-fit: cover; border-radius: var(--radius-sm);
  border: 1px solid var(--line); flex-shrink: 0;
}
.dropzone-preview-info { display: flex; flex-direction: column; align-items: flex-start; gap: .5rem; min-width: 0; }
.dropzone-preview-info span {
  font-size: .88rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; max-width: 16rem;
}

/* Existing-screenshot gallery — its own full-width section below the
   Journal card (TRADE_JOURNAL.md UI pass), not squeezed into a column
   next to the notes/tags fields. Responsive grid, not a fixed-width
   flex row, so it actually uses the full row width on a wide screen. */
.journal-attachments {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 1rem;
}
.journal-attachment-card {
  padding: .65rem;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.journal-attachment-card img {
  width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: .4rem;
  display: block; margin-bottom: .45rem;
}
.journal-attachment-card p { font-size: .8rem; margin: 0 0 .45rem; color: var(--ink-soft); }

/* Journal dashboard — stat cards + equity curve (TRADE_JOURNAL.md).
   Chart is hand-built inline SVG (see TRADE_JOURNAL.md §7 — no charting
   library), so it always picks up the site's own tokens/colors. */
.journal-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}
.journal-stat-card {
  padding: 1.1rem 1.25rem;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.journal-stat-label { display: block; font-size: .8rem; color: var(--ink-faint); margin-bottom: .4rem; }
.journal-stat-value {
  display: block; font-family: var(--font-mono); font-size: 1.35rem;
  font-weight: 700; color: var(--ink); line-height: 1.2;
}
.journal-stat-value.is-positive { color: var(--buy); }
.journal-stat-value.is-negative { color: var(--sell); }
.journal-stat-sub { display: block; font-size: .78rem; color: var(--ink-faint); margin-top: .3rem; }

.journal-equity-card { padding: 1.5rem; margin-bottom: 2rem; }
.journal-equity-card h2 { margin: 0 0 1rem; font-size: 1.1rem; }
.journal-equity-chart { width: 100%; height: 11rem; display: block; }
.journal-equity-empty { color: var(--ink-soft); font-size: .9rem; padding: 2.5rem 0; text-align: center; }

/* Equity curve layout: a narrow Y-axis label column beside the chart,
   an X-axis label row below it. Labels are plain HTML, not SVG <text>
   — the chart's preserveAspectRatio="none" stretches x/y independently,
   which would render in-SVG text visibly distorted. */
.journal-equity-layout { display: flex; gap: .75rem; }
.journal-equity-axis-y {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 11rem;
  font-size: .72rem;
  font-family: var(--font-mono);
  color: var(--ink-faint);
  text-align: right;
  flex-shrink: 0;
}
.journal-equity-main { flex: 1; min-width: 0; }
.journal-equity-chart-wrap { position: relative; }
.journal-equity-axis-x {
  display: flex;
  justify-content: space-between;
  margin-top: .5rem;
  font-size: .72rem;
  color: var(--ink-faint);
}

.journal-equity-crosshair-line {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--line);
  pointer-events: none;
}
.journal-equity-crosshair-dot {
  position: absolute;
  width: .55rem;
  height: .55rem;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg-raised);
  pointer-events: none;
}
/* Same author-origin-display-beats-[hidden] issue already fixed
   elsewhere in this file (.market-card[hidden] etc.) — explicit
   safeguard here even though neither rule above sets display. */
.journal-equity-crosshair-line[hidden], .journal-equity-crosshair-dot[hidden] { display: none; }

/* Journal — AI insight card (TRADE_JOURNAL.md §4) */
.journal-insight-card {
  padding: 1.5rem;
  margin-bottom: 2rem;
  border-left: 3px solid var(--accent);
}
.journal-insight-card h2 { margin: 0 0 .75rem; font-size: 1.1rem; }
.journal-insight-card p { margin: 0 0 .75rem; line-height: 1.6; color: var(--ink-soft); }
.journal-insight-period { font-size: .8rem; color: var(--ink-faint); }

/* Journal — trade outcome donut (multi-circle stroke-dasharray technique,
   TRADE_JOURNAL.md's "hand-built SVG, no charting library" rule) */
.journal-mini-charts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.25rem;
  margin-bottom: 2rem;
}
.journal-mini-chart-card { padding: 1.35rem 1.5rem; }
.journal-mini-chart-card h3 { margin: 0 0 1.1rem; font-size: .95rem; color: var(--ink-soft); }
.journal-mini-chart-card .journal-report-row { margin-bottom: .5rem; }
.journal-mini-stat-card { display: flex; flex-direction: column; justify-content: center; }
.journal-donut-row { display: flex; align-items: center; gap: 2rem; flex-wrap: wrap; }
.journal-donut-chart { width: 9.5rem; height: 9.5rem; flex-shrink: 0; }
.journal-donut-hole { fill: var(--bg-raised); stroke: none; }
.journal-donut-ring { fill: transparent; stroke: var(--line); stroke-width: 3; }
.journal-donut-segment {
  fill: transparent;
  stroke-width: 3;
  transition: stroke-dasharray .4s var(--ease-out), stroke-dashoffset .4s var(--ease-out);
}
.journal-donut-center-value {
  text-anchor: middle; font-family: var(--font-mono); font-size: 6px;
  font-weight: 700; fill: var(--ink);
}
.journal-donut-center-label { text-anchor: middle; font-size: 3px; fill: var(--ink-faint); }
.journal-donut-legend { display: flex; flex-direction: column; gap: .65rem; }
.journal-donut-legend-item { display: flex; align-items: center; gap: .55rem; font-size: .88rem; color: var(--ink-soft); }
.journal-donut-legend-item i { width: .7rem; height: .7rem; border-radius: 50%; display: inline-block; flex-shrink: 0; }

/* Shared chart tooltip — wired by static/js/chart-tooltip.js, used by
   every hand-built chart in the Journal via [data-tooltip]. Glass-panel
   look (same color-mix + backdrop-filter recipe as .site-header) plus a
   branded glow ring (--shadow-glow, same token the hero pipeline/pricing
   card use) instead of a flat gray box, and a fade + slide-up entrance
   instead of popping in instantly. Two-line layout: .chart-tooltip-title
   (the headline — label + value) and .chart-tooltip-sub (dimmer supporting
   detail, e.g. trade count/win rate) instead of cramming everything onto
   one line — .chart-tooltip-sub only renders when [data-tooltip-sub] was
   actually set (see chart-tooltip.js), so callers that only need one line
   (donut segments, calendar days, the equity curve) look identical to
   before. */
.chart-tooltip {
  position: absolute;
  z-index: 300;
  display: flex;
  flex-direction: column;
  gap: .2rem;
  padding: .55rem .8rem;
  background: color-mix(in srgb, var(--bg-raised) 92%, transparent);
  backdrop-filter: blur(10px) saturate(160%);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  font-family: var(--font-mono);
  box-shadow: var(--shadow-glow);
  pointer-events: none;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(4px) scale(.96);
  transition: opacity .15s var(--ease-out), transform .15s var(--ease-out);
}
.chart-tooltip.is-visible { opacity: 1; transform: translateY(0) scale(1); }
.chart-tooltip-title { font-size: .8rem; font-weight: 700; color: var(--ink); }
.chart-tooltip-sub { font-size: .7rem; font-weight: 500; color: var(--ink-faint); }
.chart-tooltip-sub[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .chart-tooltip { transition: none; transform: none; }
  .chart-tooltip.is-visible { transform: none; }
}
/* Author-origin styling above ties in specificity with the browser's own
   [hidden]{display:none} — same bug already hit and fixed elsewhere in
   this file (.market-card[hidden] etc.) — except here nothing sets
   display on .chart-tooltip itself, so no override is actually needed;
   left as an explicit safeguard anyway since a future rule easily could. */
.chart-tooltip[hidden] { display: none; }

.journal-equity-hover { fill: transparent; cursor: crosshair; }

/* Journal — Daily P&L bar chart (TRADE_JOURNAL.md), pure CSS bars
   (not SVG) so value labels never fight the non-uniform-scaling
   distortion the equity curve's preserveAspectRatio="none" causes. */
.journal-bar-card { padding: 1.5rem; margin-bottom: 2rem; }
.journal-bar-card h2 { margin: 0 0 1.25rem; font-size: 1.1rem; }
.journal-bar-chart { display: flex; gap: .4rem; height: 11rem; }
.journal-bar-chart-col {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.journal-bar-chart-half { flex: 1; display: flex; position: relative; }
.journal-bar-chart-half-pos { align-items: flex-end; border-bottom: 1px solid var(--line); }
.journal-bar-chart-half-neg { align-items: flex-start; }
.journal-bar-chart-bar {
  position: relative;
  width: 100%;
  min-height: 2px;
  cursor: default;
  transition: height .3s var(--ease-out);
}
.journal-bar-chart-half-pos .journal-bar-chart-bar { background: var(--buy); border-radius: 2px 2px 0 0; }
.journal-bar-chart-half-neg .journal-bar-chart-bar { background: var(--sell); border-radius: 0 0 2px 2px; }
.journal-bar-chart-value {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  font-size: .62rem;
  font-family: var(--font-mono);
  color: var(--ink-faint);
  white-space: nowrap;
}
.journal-bar-chart-half-pos .journal-bar-chart-value { bottom: 100%; margin-bottom: .2rem; }
.journal-bar-chart-half-neg .journal-bar-chart-value { top: 100%; margin-top: .2rem; }
.journal-bar-chart-label {
  font-size: .68rem;
  color: var(--ink-faint);
  text-align: center;
  margin-top: .4rem;
}
@media (max-width: 700px) {
  .journal-bar-chart-value, .journal-bar-chart-label { display: none; }
}

/* Top-of-page tabs shared between the Journal dashboard and Trade log */
.journal-tabs { display: flex; gap: .5rem; margin-bottom: 1.5rem; flex-wrap: wrap; }
.journal-tab {
  padding: .5rem 1rem;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  font-size: .88rem;
  font-weight: 600;
  transition: border-color .2s var(--ease-out), color .2s var(--ease-out), background .2s var(--ease-out);
}
.journal-tab:hover { border-color: var(--accent); color: var(--ink); }
.journal-tab.is-active { background: var(--accent-soft); border-color: transparent; color: var(--accent-ink); }

/* Journal — playbooks grid (TRADE_JOURNAL.md) */
.journal-playbook-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: 1.25rem;
}
.journal-playbook-card {
  padding: 1.25rem 1.5rem;
  border-top: 3px solid var(--playbook-color, var(--accent));
  display: flex;
  flex-direction: column;
  gap: .9rem;
}
.journal-playbook-card-head { display: flex; align-items: center; gap: .6rem; }
.journal-playbook-card-head h3 { margin: 0; font-size: 1.05rem; }
.journal-playbook-swatch {
  width: .85rem; height: .85rem; border-radius: 50%;
  background: var(--playbook-color, var(--accent)); flex-shrink: 0;
}
.journal-playbook-description { margin: 0; font-size: .88rem; color: var(--ink-soft); line-height: 1.5; }
.journal-playbook-stats { display: flex; gap: 1.5rem; }
.journal-playbook-actions { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: .25rem; }

/* Journal — calendar (TRADE_JOURNAL.md) */
.journal-calendar-nav {
  display: flex; align-items: center; justify-content: center; gap: 1.5rem;
  margin-bottom: 1rem;
}
.journal-calendar-nav h2 { margin: 0; font-size: 1.2rem; min-width: 12rem; text-align: center; }
.journal-calendar-weekdays {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: .5rem;
  margin-bottom: .5rem; text-align: center;
}
.journal-calendar-weekdays span { font-size: .8rem; color: var(--ink-faint); font-weight: 600; }
.journal-calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: .5rem; }
.journal-calendar-day {
  position: relative;
  aspect-ratio: 1 / 1;
  min-height: 5.5rem;
  padding: .5rem;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: border-color .2s var(--ease-out);
}
.journal-calendar-day:hover { border-color: var(--accent); }
.journal-calendar-day.is-outside { opacity: .35; }
.journal-calendar-day.is-today { border-color: var(--accent); border-width: 2px; }
.journal-calendar-day-heat { position: absolute; inset: 0; z-index: 0; }
.journal-calendar-day-num {
  position: relative; z-index: 1; font-size: .82rem; font-weight: 600; color: var(--ink-soft);
}
.journal-calendar-day-pnl {
  position: relative; z-index: 1; font-family: var(--font-mono); font-weight: 700;
  font-size: 1rem; margin-top: auto;
}
.journal-calendar-day-count { position: relative; z-index: 1; font-size: .72rem; color: var(--ink-faint); }
.journal-calendar-day-dot {
  position: absolute; top: .5rem; right: .5rem; z-index: 1;
  width: .4rem; height: .4rem; border-radius: 50%; background: var(--gold);
}
@media (max-width: 700px) {
  .journal-calendar-day { min-height: 3.5rem; padding: .35rem; }
  .journal-calendar-day-num { font-size: .72rem; }
  .journal-calendar-day-pnl { font-size: .78rem; }
  .journal-calendar-day-count { display: none; }
}

/* Journal — reports breakdown bars (TRADE_JOURNAL.md) */
.journal-report-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
}
@media (max-width: 900px) {
  .journal-report-grid { grid-template-columns: 1fr; }
}
.journal-report-card { padding: 1.25rem 1.5rem; display: flex; flex-direction: column; justify-content: center; }
.journal-report-card h3 { margin: 0 0 1rem; font-size: 1rem; }
.journal-report-row {
  display: grid;
  grid-template-columns: 6rem 1fr 4.5rem;
  align-items: center;
  gap: .75rem;
  margin-bottom: .55rem;
  font-size: .85rem;
}
.journal-report-row:last-child { margin-bottom: 0; }
.journal-report-label {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-soft);
}
.journal-report-bar-track {
  position: relative; height: .5rem; background: var(--bg-sunken);
  border-radius: 999px; overflow: hidden;
}
.journal-report-bar-fill {
  position: absolute; left: 0; top: 0; bottom: 0; border-radius: 999px;
  transition: width .3s var(--ease-out);
}
.journal-report-value {
  text-align: right; font-family: var(--font-mono); font-weight: 700; font-size: .82rem;
}

/* Journal — Reports axis-anchored bar charts (replaces the flat-fill
   .journal-report-* rows above for the Reports page specifically; the
   Journal dashboard's small "P&L by side" mini widget still uses the
   plain fill-bar version above, unchanged). Gridlines + a $0 zero-line,
   bars growing left/right from zero instead of always from the left
   edge — same data as .journal-report-*, presented as a real chart. */
.journal-axis-card { padding: 1.25rem 1.5rem 1.5rem; }
.journal-axis-card h3 {
  margin: 0 0 1.25rem; font-size: 1rem;
  display: flex; align-items: center; gap: .55rem;
}
.journal-axis-card h3::before {
  content: ""; width: .5rem; height: .5rem; border-radius: 50%; flex-shrink: 0;
  background: var(--accent);
}
/* Cycles the title dot through 3 brand accents per card, in DOM order —
   purely decorative grouping, doesn't mean anything about the card's own
   data (unlike --bar-color above, which is real signal). */
.journal-report-grid > .journal-axis-card:nth-child(3n+2) h3::before { background: var(--gold); }
.journal-report-grid > .journal-axis-card:nth-child(3n) h3::before { background: var(--magenta); }
.journal-axis-body { display: flex; gap: .75rem; }
.journal-axis-labels {
  flex: 0 0 6rem; display: flex; flex-direction: column; gap: .5rem; padding-top: .1rem;
}
.journal-axis-label-cell {
  height: 1.5rem; display: flex; align-items: center;
  font-size: .8rem; color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.journal-axis-plot-wrap { flex: 1; min-width: 0; }
.journal-axis-plot {
  /* Narrower than the wrap, not full-width — a row's $ value label floats
     just past its bar's edge (see .journal-axis-value below) and can land
     right at the 100% mark for the largest bar in a card. This reserved
     strip keeps that label inside the card instead of spilling past its
     right edge/border. */
  position: relative; width: calc(100% - 4.75rem);
  display: flex; flex-direction: column; gap: .5rem;
  padding-bottom: .6rem; border-bottom: 1px solid var(--line-soft);
}
.journal-axis-gridline {
  position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line-soft);
}
.journal-axis-gridline.is-zero { background: var(--line); width: 1px; }
.journal-axis-row { position: relative; height: 1.5rem; border-radius: 4px; }
.journal-axis-bar {
  /* Gradient fill (soft -> full-strength --bar-color, set inline per row
     to --buy/--sell — buy/sell stay the semantic P&L colors, this never
     substitutes the brand violet/gold ramp) + a matching glow instead of
     a flat solid rect, plus a one-shot grow-in from the $0 zero-line on
     load (transform-origin flips per row via .is-negative — see below)
     instead of appearing at full width instantly. Only the outer tip is
     rounded (the end away from zero) — the zero-line edge stays flush/
     square, reading as anchored to the axis rather than a floating pill. */
  position: absolute; top: 15%; bottom: 15%; border-radius: 0 4px 4px 0; min-width: 2px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--bar-color) 55%, transparent), var(--bar-color));
  box-shadow: 0 0 10px color-mix(in srgb, var(--bar-color) 32%, transparent);
  transform-origin: left center;
  animation: journal-bar-grow .55s var(--ease-out) both;
  transition: left .3s var(--ease-out), width .3s var(--ease-out),
              box-shadow .2s var(--ease-out), filter .2s var(--ease-out);
}
.journal-axis-bar.is-negative {
  background: linear-gradient(270deg, color-mix(in srgb, var(--bar-color) 55%, transparent), var(--bar-color));
  border-radius: 4px 0 0 4px;
  transform-origin: right center;
}
.journal-axis-row:hover .journal-axis-bar, .journal-axis-row:focus-visible .journal-axis-bar {
  filter: brightness(1.16);
  box-shadow: 0 0 18px color-mix(in srgb, var(--bar-color) 55%, transparent);
}
@keyframes journal-bar-grow {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}
@media (prefers-reduced-motion: reduce) {
  .journal-axis-bar { animation: none; }
}
.journal-axis-value {
  /* Fades/slides in just after its bar finishes growing (see the inline
     animation-delay in reports.html — bar delay + a fixed offset) rather
     than appearing instantly alongside it. */
  position: absolute; top: 50%;
  white-space: nowrap; font-family: var(--font-mono); font-weight: 700; font-size: .78rem;
  opacity: 0;
  animation: journal-value-fade .3s var(--ease-out) both;
}
@keyframes journal-value-fade {
  from { opacity: 0; transform: translate(.15rem, -50%); }
  to { opacity: 1; transform: translate(.5rem, -50%); }
}
@media (prefers-reduced-motion: reduce) {
  .journal-axis-value { animation: none; opacity: 1; transform: translate(.5rem, -50%); }
}
.journal-axis-ticks {
  position: relative; width: calc(100% - 4.75rem); height: 1.1rem; margin-top: .4rem;
}
.journal-axis-ticks span {
  position: absolute; top: 0; transform: translateX(-50%);
  font-size: .7rem; color: var(--ink-faint); font-family: var(--font-mono); white-space: nowrap;
}
@media (max-width: 640px) {
  .journal-axis-labels { flex-basis: 4.25rem; }
}

/* Journal — AI assistant chat (static/js/journal-ai-chat.js)
   Deliberately not a "messenger app" layout (circular avatars + symmetric
   rounded bubbles) — that read as a generic templated chat widget. Instead
   this borrows the site's own "live wire" vocabulary already used
   elsewhere (--ramp gradient, .live-dot pulse, mono uppercase labels,
   --spotlight glow): assistant replies render as full-width readout
   panels with a gradient edge, user turns as compact right-aligned tags —
   an asymmetric "terminal log" feel instead of two mirrored bubble
   columns. */
/* EZRA-style full-page Journal AI layout */
.ja-full-page {
  display: flex;
  position: relative;
  height: 100%;
  background: #030208;
  overflow: hidden;
}

/* Lives outside .ja-sidebar-main on purpose — the collapse toggle sits
   inside the sidebar header, so it collapses away along with it
   (width: 0, overflow: hidden). Without a separate always-reachable
   button, a collapsed sidebar had no way to reopen. Shown/hidden by JS
   in lockstep with .is-collapsed instead of relying on CSS siblings, so
   it works regardless of where in the DOM either button lives. */
.ja-sidebar-reopen {
  position: absolute;
  top: 1.35rem;
  left: 1rem;
  z-index: 20;
  width: 2.1rem;
  height: 2.1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: .5rem;
  color: var(--ink-soft);
  cursor: pointer;
  transition: all .2s var(--ease-out);
}
.ja-sidebar-reopen:hover {
  background: rgba(255, 255, 255, 0.1);
  color: var(--ink);
}
.ja-sidebar-reopen[hidden] { display: none; }

.ja-sidebar-main {
  width: 260px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding: 1.5rem 1rem;
  background: #030208;
  border-right: 1px solid rgba(255, 255, 255, 0.05);
  overflow: hidden;
  transition: width .3s var(--ease-out), margin-left .3s var(--ease-out);
}
.ja-sidebar-main.is-collapsed {
  width: 0;
  padding: 0;
  border-right: none;
  overflow: hidden;
}

.ja-sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0 0.5rem;
}
.ja-sidebar-header h2 {
  font-size: .82rem;
  font-weight: 600;
  color: var(--ink);
  margin: 0;
}
.ja-sidebar-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  background: rgba(255, 255, 255, 0.05);
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: 4px;
  transition: all .2s var(--ease-out);
}
.ja-sidebar-toggle:hover {
  background: rgba(255, 255, 255, 0.1);
  color: var(--ink);
}

.ja-new-chat-btn {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-shrink: 0;
  font-family: var(--font-body);
  font-size: .78rem;
  font-weight: 600;
  color: var(--ink);
  background: linear-gradient(135deg, var(--accent), var(--accent-soft));
  border: 1px solid var(--accent);
  border-radius: .6rem;
  padding: .7rem 1rem;
  cursor: pointer;
  transition: all .2s var(--ease-out);
}
.ja-new-chat-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(108, 92, 231, 0.3);
}

.ja-sidebar-search {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-shrink: 0;
  padding: .6rem .65rem;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: .6rem;
  color: var(--ink-faint);
}
.ja-sidebar-search input {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: .76rem;
}
.ja-sidebar-search input:focus { outline: none; }
.ja-sidebar-search input::placeholder { color: var(--ink-faint); }

.ja-sidebar-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
}
.ja-sidebar-list::-webkit-scrollbar { width: 6px; }
.ja-sidebar-list::-webkit-scrollbar-track { background: transparent; }
.ja-sidebar-list::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); border-radius: 3px; }
.ja-sidebar-list::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.3); }

.ja-conv-group { display: flex; flex-direction: column; gap: .4rem; margin-bottom: .5rem; }
.ja-conv-group-label {
  font-family: var(--font-mono);
  font-size: .62rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.4);
  padding: .5rem .65rem 0;
}
.ja-sidebar-empty { color: var(--ink-faint); font-size: .74rem; padding: 1rem .5rem; text-align: center; }
.ja-sidebar-empty[hidden] { display: none; }

.ja-conv-item-wrapper {
  position: relative;
  display: flex;
  align-items: stretch;
}
.ja-conv-item-wrapper[hidden], .ja-conv-group[hidden] { display: none; }
.ja-conv-item {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: .2rem;
  padding: .55rem 2rem .55rem .65rem;
  border-radius: .5rem;
  color: rgba(255, 255, 255, 0.7);
  transition: all .15s var(--ease-out);
  text-decoration: none;
}
.ja-conv-item-wrapper:hover .ja-conv-item {
  background: rgba(255, 255, 255, 0.08);
  color: var(--ink);
}
.ja-conv-item.is-active {
  background: linear-gradient(135deg, rgba(108, 92, 231, 0.3), rgba(108, 92, 231, 0.1));
  border: 1px solid rgba(108, 92, 231, 0.5);
  color: var(--ink);
}
.ja-conv-title {
  font-size: .76rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ja-conv-time {
  font-family: var(--font-mono);
  font-size: .6rem;
  color: rgba(255, 255, 255, 0.4);
}
.ja-conv-delete-form { position: absolute; right: .4rem; top: 50%; transform: translateY(-50%); }
.ja-conv-delete {
  display: none;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: .4rem;
  background: transparent;
  color: rgba(255, 255, 255, 0.4);
  border: none;
  cursor: pointer;
  transition: all .15s var(--ease-out);
}
.ja-conv-item-wrapper:hover .ja-conv-delete { display: flex; }
.ja-conv-delete:hover { color: var(--sell); background: rgba(239, 68, 68, 0.2); }

@media (max-width: 1000px) {
  .ja-sidebar-toggle { display: flex; }
}

/* Journal AI - Full page EZRA-style layout */
.ja-main-content {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: #030208;
  position: relative;
}

.ja-chat-area {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.1) transparent;
  padding: 0;
}
.ja-chat-area::-webkit-scrollbar { width: 8px; }
.ja-chat-area::-webkit-scrollbar-track { background: transparent; }
.ja-chat-area::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 4px; }
.ja-chat-area::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.2); }

.ja-empty-view {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 3rem 2rem;
  text-align: center;
}
.ja-empty-view[hidden] {
  display: none;
}
.ja-empty-view[data-empty-state]:not([hidden]) ~ .ja-messages {
  display: none;
}
.ja-brand-section {
  max-width: 600px;
  margin-bottom: 2rem;
}
.ja-logo {
  margin-bottom: 1rem;
}
.ja-logo .logo-mark {
  height: 2.75rem;
  margin: 0 auto;
}
.ja-empty-view h1 {
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 .6rem;
  line-height: 1.2;
}
.ja-empty-view p {
  font-size: 1rem;
  color: rgba(255, 255, 255, 0.6);
  margin: 0;
  line-height: 1.6;
}

.ja-cards-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: .6rem;
  max-width: 700px;
}
.ja-feature-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .35rem;
  padding: .7rem .8rem;
  background: rgba(20, 20, 35, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: .65rem;
  cursor: pointer;
  transition: all .2s var(--ease-out);
}
.ja-feature-card:hover {
  border-color: rgba(108, 92, 231, 0.5);
  background: rgba(108, 92, 231, 0.1);
  transform: translateY(-2px);
}
.ja-card-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.7rem;
  height: 1.7rem;
  background: linear-gradient(135deg, rgba(108, 92, 231, 0.2), rgba(108, 92, 231, 0.05));
  border: 1px solid rgba(108, 92, 231, 0.3);
  border-radius: .5rem;
  color: var(--accent);
}
.ja-card-icon svg { width: .9rem; height: .9rem; }
.ja-feature-card h3 {
  font-size: .8rem;
  font-weight: 600;
  color: var(--ink);
  margin: 0;
}
.ja-card-desc {
  font-size: .72rem;
  color: rgba(255, 255, 255, 0.6);
  margin: 0;
}

.ja-messages {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  padding: 2rem;
}
.ja-msg {
  display: flex;
  gap: 1rem;
  animation: slideIn .3s ease-out;
}
.ja-msg[hidden] {
  display: none;
}
@keyframes slideIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.ja-msg-user {
  justify-content: flex-end;
}
.ja-msg-avatar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  background: var(--accent-soft);
  border-radius: .6rem;
  color: var(--accent-ink);
  font-size: .85rem;
  font-weight: 600;
}
.ja-msg-assistant .ja-msg-avatar {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  padding: .4rem;
}
.ja-msg-assistant .ja-msg-avatar img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: .3rem;
}
.ja-msg-bubble {
  max-width: 65%;
  padding: 1rem 1.2rem;
  background: rgba(20, 20, 35, 0.4);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: .8rem;
  color: var(--ink);
  line-height: 1.6;
}
.ja-msg-user .ja-msg-bubble {
  background: linear-gradient(135deg, rgba(108, 92, 231, 0.3), rgba(108, 92, 231, 0.1));
  border-color: rgba(108, 92, 231, 0.3);
}
.ja-msg-bubble p { margin: 0; }
.ja-msg-bubble p + p { margin-top: .5rem; }

.journal-assistant-thread::-webkit-scrollbar { width: 8px; }
.journal-assistant-thread::-webkit-scrollbar-track { background: transparent; }
.journal-assistant-thread::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: var(--radius-pill);
  border: 2px solid transparent;
  background-clip: padding-box;
}
.journal-assistant-thread::-webkit-scrollbar-thumb:hover {
  background: var(--accent);
  background-clip: padding-box;
}
.journal-assistant-empty {
  margin: auto;
  max-width: 34rem;
  color: var(--ink-soft);
  font-size: .92rem;
  line-height: 1.6;
  text-align: center;
  padding: 2rem 0;
}
.ja-empty-header {
  text-align: center;
  margin-bottom: 3rem;
}
.ja-empty-logo {
  margin-bottom: 2rem;
}
.ja-empty-logo .logo-mark {
  height: 5rem;
  margin: 0 auto;
}
.ja-empty-title {
  font-size: 2.2rem;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 1rem;
  line-height: 1.2;
}
.ja-empty-subtitle {
  font-size: .95rem;
  color: var(--ink-soft);
  max-width: 600px;
  margin: 0 auto;
  line-height: 1.5;
}

.ja-suggestions-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
  margin-top: 2.5rem;
}
.ja-suggestion-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.2rem;
  padding: 2rem 1.5rem;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  cursor: pointer;
  text-align: center;
  transition: border-color .2s var(--ease-out), background .2s var(--ease-out), transform .15s var(--ease-out);
}
.ja-suggestion-card:hover {
  border-color: var(--accent);
  background: var(--bg-sunken);
  transform: translateY(-2px);
}
.ja-suggestion-card-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  background: var(--accent-soft);
  border-radius: var(--radius-md);
  color: var(--accent-ink);
}
.ja-suggestion-card-icon svg {
  width: 1.5rem;
  height: 1.5rem;
}
.ja-suggestion-card-content {
  flex: 1;
}
.ja-suggestion-card-title {
  font-size: .95rem;
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 .4rem;
}
.ja-suggestion-card-text {
  font-size: .82rem;
  color: var(--ink-soft);
  margin: 0;
  line-height: 1.4;
}

@media (max-width: 1000px) {
  .ja-suggestions-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
  .ja-suggestions-grid { grid-template-columns: 1fr; }
  .ja-empty-title { font-size: 1.6rem; }
}

.ja-row { display: flex; align-items: flex-start; gap: .85rem; max-width: 46rem; }
/* Author-origin display above ties in specificity with the browser's own
   [hidden]{display:none} and wins by cascade origin — same bug already
   hit and fixed for .market-card[hidden] etc. Without this, the
   thinking-indicator row (rendered with the hidden attribute, toggled
   via JS) would show permanently from page load instead of only while
   waiting on a reply. */
.ja-row[hidden] { display: none; }
.ja-assistant { align-self: flex-start; width: 100%; }
.ja-assistant .ja-panel { flex: 1; }
.ja-user { align-self: flex-end; flex-direction: row-reverse; }

/* No per-message "You"/"Journal AI" text label — the avatar alone
   identifies the sender. */
.ja-avatar {
  position: relative;
  width: 2.75rem;
  height: 2.75rem;
  flex-shrink: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  text-transform: uppercase;
}
.ja-avatar-user { background: var(--accent-soft); color: var(--accent-ink); overflow: hidden; }
/* No overflow:hidden here (unlike .ja-avatar-user) — .ja-avatar-status
   sits right at this circle's edge and would get clipped by it. The
   theme-logo <img> pair is clipped to the circle on its own instead. */
.ja-avatar-assistant { background: var(--bg-sunken); border: 1px solid var(--line); padding: 8px; }
.ja-avatar-assistant img { border-radius: 50%; }
.ja-avatar-assistant img { width: 100%; height: 100%; object-fit: contain; }
.ja-avatar-status {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: .6rem;
  height: .6rem;
  border-radius: 50%;
  background: var(--buy);
  border: 2px solid var(--bg-raised);
  animation: pulse-dot 1.9s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .ja-avatar-status { animation: none; }
}

.ja-panel {
  position: relative;
  padding: 1rem 1.2rem 1rem 1.4rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--line);
  background: var(--bg-raised);
  min-width: 0;
}
.ja-panel::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  border-radius: var(--radius-md) 0 0 var(--radius-md);
  background: var(--ramp);
}
/* Assistant replies render server-sanitized markdown (trading/views.py's
   _render_assistant_markdown) — bold, lists, the odd table — so .ja-panel
   needs rules for more than just <p>. */
.ja-panel > *:first-child { margin-top: 0; }
.ja-panel > *:last-child { margin-bottom: 0; }
.ja-panel p { margin: 0 0 .75rem; line-height: 1.6; font-size: .92rem; color: var(--ink-soft); }
.ja-panel strong { color: var(--ink); font-weight: 600; }
.ja-panel h3, .ja-panel h4 {
  margin: 1rem 0 .5rem;
  color: var(--ink);
  font-family: var(--font-display);
  line-height: 1.3;
}
.ja-panel h3 { font-size: 1rem; }
.ja-panel h4 { font-size: .94rem; }
.ja-panel ul, .ja-panel ol { margin: 0 0 .75rem; padding-left: 1.25rem; color: var(--ink-soft); }
.ja-panel li { margin-bottom: .3rem; line-height: 1.55; }
.ja-panel li::marker { color: var(--accent-ink); }
.ja-panel blockquote {
  margin: 0 0 .75rem;
  padding: .1rem 0 .1rem 1rem;
  border-left: 2px solid var(--accent);
  color: var(--ink-faint);
  font-style: italic;
}
.ja-panel code {
  font-family: var(--font-mono);
  font-size: .84em;
  background: var(--code-bg);
  color: var(--code-ink);
  padding: .1rem .35rem;
  border-radius: 4px;
}
.ja-panel pre {
  margin: 0 0 .75rem;
  padding: .8rem 1rem;
  background: var(--code-bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow-x: auto;
}
.ja-panel pre code { background: none; padding: 0; }
.ja-panel table { width: 100%; margin: 0 0 .75rem; border-collapse: collapse; font-size: .86rem; }
.ja-panel th, .ja-panel td { padding: .45rem .6rem; border: 1px solid var(--line); text-align: left; }
.ja-panel th { color: var(--ink); font-weight: 600; background: var(--bg-sunken); }
.ja-panel td { color: var(--ink-soft); }

.ja-user .ja-panel {
  padding: .7rem 1.05rem;
  background: var(--accent-soft);
  border-color: transparent;
}
.ja-user .ja-panel::before { display: none; }
.ja-user .ja-panel p { color: var(--ink); white-space: pre-wrap; }

.ja-thinking {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  min-width: 11rem;
}
/* Shimmering skeleton lines — reads as "a reply of roughly this shape is
   being composed," the standard modern-AI-chat loading pattern, instead
   of a generic indeterminate progress bar. Uses the accent tokens (not
   --line/--line-soft) because those structural-border tokens sit almost
   flush with the dark bubble background, which made the loader read as
   an inert dark box instead of an animating shimmer. */
.ja-thinking-line {
  height: .6rem;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--accent-soft) 25%, var(--accent-glow) 50%, var(--accent-soft) 75%);
  background-size: 400% 100%;
  animation: ja-shimmer 1.6s ease-in-out infinite;
}
.ja-thinking-line-1 { width: 85%; }
.ja-thinking-line-2 { width: 55%; }
@keyframes ja-shimmer {
  0%   { background-position: 100% 0; }
  100% { background-position: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ja-thinking-line { animation: none; background: var(--accent-soft); }
}

/* Compact equity-curve sparkline attached to a reply — templates/trading/
   journal/_assistant_chart.html, only rendered when the trader's own
   question calls for a chart (see trading/views.py). Deliberately not
   interactive (no crosshair) — equity-crosshair.js only wires up chart
   instances present at page load, and this can land in the DOM well
   after that via the AJAX reply. */
.ja-chart { margin-top: .9rem; padding-top: .9rem; border-top: 1px dashed var(--line); }
.ja-chart-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: .5rem; gap: .5rem; }
.ja-chart-title {
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.ja-chart-sub { font-size: .74rem; color: var(--ink-faint); white-space: nowrap; }
.ja-chart-svg { width: 100%; height: 5rem; display: block; }
.ja-chart-axis {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: .68rem;
  color: var(--ink-faint);
  margin-top: .25rem;
}

.journal-assistant-form {
  display: flex;
  gap: .6rem;
  align-items: flex-end;
  padding: .4rem .4rem .4rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg-sunken);
  transition: border-color .2s var(--ease-out), box-shadow .2s var(--ease-out);
}
.journal-assistant-form:focus-within {
  border-color: var(--accent);
  box-shadow: var(--shadow-glow);
}
.journal-assistant-form textarea {
  flex: 1;
  padding: .7rem 0;
  font-family: var(--font-body);
  font-size: .92rem;
  line-height: 1.5;
  color: var(--ink);
  background: transparent;
  border: none;
  resize: none;
  max-height: 12.5rem;
  overflow-y: auto;
}
.journal-assistant-form textarea:focus { outline: none; }
.journal-assistant-form textarea:disabled { opacity: .6; }
.ja-send {
  position: relative;
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ramp);
  color: var(--on-accent);
  border: none;
  cursor: pointer;
  transition: transform .15s var(--ease-out), opacity .15s var(--ease-out);
}
.ja-send:hover { transform: scale(1.06); }
.ja-send:disabled { opacity: .5; cursor: not-allowed; transform: none; }
.ja-send-spinner {
  display: none;
  width: 1rem;
  height: 1rem;
  border: 2px solid rgba(255, 255, 255, .4);
  border-top-color: var(--on-accent);
  border-radius: 50%;
  animation: ja-spin .7s linear infinite;
}
.ja-send.is-loading .ja-send-icon { display: none; }
.ja-send.is-loading .ja-send-spinner { display: block; }
@keyframes ja-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .ja-send-spinner { animation: none; }
}
.ja-composer-hint {
  margin: .55rem 0 0;
  text-align: center;
  font-size: .72rem;
  color: var(--ink-faint);
}
.ja-composer-hint kbd {
  font-family: var(--font-mono);
  font-size: .68rem;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: .05rem .3rem;
}

.ja-composer {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: .6rem;
  padding: 1.5rem 2rem;
}
.ja-input-wrapper {
  display: flex;
  gap: .8rem;
  align-items: flex-end;
  max-width: 48rem;
  margin: 0 auto;
  width: 100%;
}
#assistant-input {
  flex: 1;
  min-height: 44px;
  max-height: 140px;
  padding: .8rem 1rem;
  background: rgba(20, 20, 35, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: .6rem;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: .9rem;
  line-height: 1.4;
  resize: none;
  transition: border-color .2s var(--ease-out);
  /* Unstyled, this textarea's native scrollbar (once typed text grows past
     max-height) renders with classic up/down arrow buttons on Windows —
     sitting right next to the send button they read as extra buttons in
     the composer. Every other scrollable area here (.ja-chat-area,
     .ja-sidebar-list) already gets this same thin/arrow-less treatment. */
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
}
#assistant-input::-webkit-scrollbar { width: 6px; }
#assistant-input::-webkit-scrollbar-track { background: transparent; }
#assistant-input::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 3px; }
#assistant-input::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.25); }
#assistant-input:focus {
  outline: none;
  border-color: rgba(108, 92, 231, 0.5);
  background: rgba(20, 20, 35, 0.8);
}
#assistant-input::placeholder { color: rgba(255, 255, 255, 0.4); }

.ja-send-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: linear-gradient(135deg, var(--accent), var(--accent-soft));
  border: none;
  border-radius: .6rem;
  color: white;
  cursor: pointer;
  transition: all .2s var(--ease-out);
}
.ja-send-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(108, 92, 231, 0.4);
}
.ja-send-btn:active { transform: translateY(0); }
.ja-send-icon { width: 18px; height: 18px; }
.ja-send-spinner {
  display: none;
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  border-top-color: white;
  border-radius: 50%;
  animation: ja-spin .7s linear infinite;
}
.ja-send-btn.is-loading .ja-send-icon { display: none; }
.ja-send-btn.is-loading .ja-send-spinner { display: block; }
@keyframes ja-spin { to { transform: rotate(360deg); } }

.ja-hint {
  display: none;
  font-size: .75rem;
  color: rgba(255, 255, 255, 0.4);
  margin: 0;
  text-align: right;
}

@media (max-width: 1000px) {
  .ja-full-page { flex-direction: column; }

  /* On phones/tablets the history list doesn't fit as a slim strip above
     the chat — it opens as its own full-page overlay instead (triggered
     by #ja-sidebar-toggle / #ja-sidebar-reopen in assistant.html, which
     also defaults it to collapsed on load at this breakpoint). */
  .ja-sidebar-main {
    width: 100%;
    border-right: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  }
  .ja-sidebar-main.is-collapsed {
    height: 0;
    max-height: 0;
    padding: 0;
    border-bottom: none;
    overflow: hidden;
  }
  .ja-sidebar-main:not(.is-collapsed) {
    position: fixed;
    inset: 0;
    z-index: 100;
    width: 100%;
    height: 100dvh;
    max-height: none;
  }
  .ja-cards-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 700px) {
  .ja-cards-grid { grid-template-columns: 1fr; gap: .5rem; }
  .ja-empty-view { padding: 1.25rem 1rem; }
  .ja-brand-section { margin-bottom: 1.25rem; }
  .ja-logo { margin-bottom: .6rem; }
  .ja-logo .logo-mark { height: 2.2rem; }
  .ja-empty-view h1 { font-size: 1.4rem; }
  .ja-empty-view p { font-size: .88rem; }
  .ja-msg-bubble { max-width: 90%; }
  .ja-composer { padding: 1rem; }
  #assistant-input { min-height: 40px; }
  .ja-send-btn { width: 40px; height: 40px; }
  .ja-hint { display: none; }
}
