/* =====================================================================
   App shell — left menu + content. Used by member pages and the admin console.
   ===================================================================== */
html, body.app { height: 100%; }
body.app { display: flex; min-height: 100vh; min-height: 100dvh; overflow: hidden; }

.side {
  --w: 244px;
  width: var(--w); flex: none; height: 100vh; height: 100dvh; display: flex; flex-direction: column;
  padding: 14px 12px 12px; gap: 6px; position: relative; z-index: 30;
  background: var(--bg); border-right: 1px solid var(--line);
  transition: width .3s var(--ease), transform .3s var(--ease);
}
.side-top { display: flex; align-items: center; gap: 10px; height: 44px; padding: 0 6px 0 8px; margin-bottom: 8px; }
.brand-mark { display: flex; align-items: center; gap: 10px; min-width: 0; }
.brand-mark .ic { width: 26px; height: 26px; }
.brand-mark b { font-size: 16.5px; font-weight: 800; letter-spacing: -.03em; white-space: nowrap; }
.brand-mark b span { color: var(--ink-3); font-weight: 600; }
.side-collapse { margin-left: auto; color: var(--ink-3); }

.nav { display: flex; flex-direction: column; gap: 2px; overflow-y: auto; overflow-x: hidden; flex: 1; padding: 2px; margin: 0 -2px; }
.nav-label { font-size: 10.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-4); padding: 14px 12px 6px; white-space: nowrap; }
.nav a {
  --nc: var(--ink-2);
  display: flex; align-items: center; gap: 11px; height: 38px; padding: 0 10px; border-radius: 10px;
  color: var(--ink-2); font-weight: 600; font-size: 13.5px; white-space: nowrap; position: relative;
  transition: background .15s, color .15s;
}
.nav a .ic { width: 18px; height: 18px; color: var(--ink-3); transition: color .15s; }
.nav a:hover { background: var(--surface-3); color: var(--ink); }
.nav a:hover .ic { color: var(--nc); }
.nav a.on { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-1); }
:root[data-theme=dark] .nav a.on { background: var(--surface-3); }
.nav a.on .ic { color: var(--nc); }
.nav a.on::before { content: ''; position: absolute; left: -12px; top: 10px; bottom: 10px; width: 3px; border-radius: 0 3px 3px 0; background: var(--nc); }
.nav a .count, .nav a .chip { margin-left: auto; }
.nav a.c-brand { --nc: var(--brand); } .nav a.c-green { --nc: var(--bull); } .nav a.c-red { --nc: var(--bear); }
.nav a.c-amber { --nc: var(--amber); } .nav a.c-sky { --nc: var(--sky); } .nav a.c-pink { --nc: var(--pink); }
.nav a.c-teal { --nc: var(--teal); } .nav a.c-violet { --nc: var(--violet); }
.live-pill { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; font-weight: 700; letter-spacing: .08em; color: var(--bull); }
.nav .live-pill { margin-left: auto; }

.side-foot { display: flex; flex-direction: column; gap: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.side-foot .row { padding: 0 4px; }
.me { display: flex; align-items: center; gap: 10px; padding: 6px; border-radius: 12px; cursor: pointer; border: 0; background: none; width: 100%; text-align: left; transition: background .15s; }
.me:hover { background: var(--surface-3); }
.me .who { min-width: 0; flex: 1; }
.me .who b { display: block; font-size: 13px; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.me .who span { display: block; font-size: 11.5px; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.plan-pill { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 750; letter-spacing: .06em; text-transform: uppercase; color: var(--amber); }

/* collapsed rail (desktop only: on phones the menu is a drawer and always shows in full) */
@media (min-width: 901px) {
  body.rail .side { --w: 68px; }
  body.rail .side .brand-mark b, body.rail .side .nav-label, body.rail .nav a span, body.rail .nav a .count, body.rail .nav a .chip,
  body.rail .nav .live-pill, body.rail .me .who, body.rail .side-foot .mkt-text { display: none; }
  body.rail .side-top { padding: 0; justify-content: center; flex-direction: column; height: auto; gap: 8px; }
  body.rail .side-collapse { margin: 0; }
  body.rail .nav a { justify-content: center; padding: 0; }
  body.rail .nav-label { height: 10px; padding: 0; }
  body.rail .side-foot .row { justify-content: center; flex-direction: column; }
  body.rail .theme-toggle { flex-direction: column; }
  body.rail .theme-toggle::before { width: 30px; }
  body.rail .theme-toggle[data-mode=dark]::before { transform: translateY(28px); }
  body.rail .me { justify-content: center; padding: 6px 0; }
  body.rail .side-collapse .ic { transform: rotate(180deg); }
  body.rail .back-link span { display: none; }
  body.rail .back-link { justify-content: center; padding: 0; }
}
/* landscape phones wider than 900px: the menu, not the page, sits beside the notch (the inset is 0 everywhere else) */
@media (min-width: 901px) {
  .side { --w: calc(244px + env(safe-area-inset-left, 0px)); padding-left: calc(12px + env(safe-area-inset-left, 0px)); }
  body.rail .side { --w: calc(68px + env(safe-area-inset-left, 0px)); }
}

/* ---------- main ---------- */
.main { flex: 1; min-width: 0; height: 100vh; height: 100dvh; overflow-y: auto; overflow-x: hidden; position: relative; scroll-behavior: smooth; }
.topbar {
  position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 14px;
  min-height: 68px; padding: 14px 32px; background: var(--glass);
  backdrop-filter: saturate(1.6) blur(14px); -webkit-backdrop-filter: saturate(1.6) blur(14px);
  border-bottom: 1px solid transparent; transition: border-color .2s;
}
.main.scrolled .topbar { border-bottom-color: var(--line); }
.topbar .ttl { display: flex; align-items: center; gap: 12px; min-width: 0; flex: 1; }
.topbar h1 { font-size: 20px; font-weight: 750; letter-spacing: -.03em; white-space: nowrap; }
.topbar .sub { font-size: 12.5px; color: var(--ink-3); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar .actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.topbar .menu-btn { display: none; }
.topbar.obbar { display: none; } /* the terminal's phone bar (flush pages, ≤900px only) */
/* an admin section's pages (Website Content) as tabs beside its name */
.topbar .sec-tabs { flex: none; }
@media (max-width: 1380px) {
  /* on their own row under the name (beside it, six tabs and a page's two buttons collide below about 1380px),
     scrolling sideways when they don't fit */
  .topbar:has(.sec-tabs) { flex-wrap: wrap; row-gap: 10px; }
  .topbar .ttl:has(.sec-tabs) { display: contents; }
  .topbar:has(.sec-tabs) .sub { flex: 1; min-width: 0; }
  .topbar:has(.sec-tabs) .actions { margin-left: auto; }
  .topbar .sec-tabs { order: 1; width: 100%; overflow-x: auto; scrollbar-width: none; }
  .topbar .sec-tabs::-webkit-scrollbar { display: none; }
  .topbar .sec-tabs a { flex: 1 0 auto; justify-content: center; }
}
@media (max-width: 560px) {
  .topbar .sec-tabs a { padding: 0 10px; }
  .topbar:has(.sec-tabs) .actions .btn { width: 38px; padding: 0; font-size: 0; gap: 0; } /* icon only; the label stays its name */
}
.page { padding: 8px 32px 48px; max-width: 1360px; margin: 0 auto; }
.page.narrow { max-width: 880px; }
.page.wide { max-width: none; }

/* flush (terminal) */
body.flush .main { overflow: hidden; }
body.flush .page { padding: 0; max-width: none; height: 100vh; }

/* admin console accent */
body.admin .side { background: var(--bg-2); }
.admin-flag { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px; border-radius: 99px; background: var(--amber-soft); color: var(--amber); font-size: 10.5px; font-weight: 750; letter-spacing: .08em; text-transform: uppercase; }
.back-link { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; margin: 0 0 4px; border-radius: 10px; color: var(--ink-3); font-size: 12.5px; font-weight: 600; }
.back-link:hover { background: var(--surface-3); color: var(--ink); }

/* market status pill (topbar / sidebar) */
.mkt { display: inline-flex; align-items: center; gap: 7px; height: 28px; padding: 0 11px; border-radius: 99px; background: var(--surface-3); font-size: 11.5px; font-weight: 650; color: var(--ink-2); white-space: nowrap; }
.mkt.open { background: var(--bull-soft); color: var(--bull); }
.mkt.pre { background: var(--amber-soft); color: var(--amber); }

/* page-level layout helpers */
.cols-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.cols-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.cols-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.cols-main { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 20px; align-items: start; }
.section-title { display: flex; align-items: center; gap: 10px; margin: 28px 0 12px; }
.section-title h2 { font-size: 15px; font-weight: 700; }
.section-title .sub { font-size: 12.5px; color: var(--ink-3); }
.section-title .actions { margin-left: auto; display: flex; gap: 8px; }
.toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }

/* scrim for mobile menu */
.scrim { display: none; }

@media (max-width: 1180px) {
  .cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cols-main { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 900px) {
  .side { position: fixed; left: 0; top: 0; bottom: 0; transform: translateX(-102%); --w: calc(272px + env(safe-area-inset-left, 0px)) !important; background: var(--surface); box-shadow: var(--shadow-pop); }
  body.menu-open .side { transform: none; }
  body.menu-open .scrim { display: block; position: fixed; inset: 0; z-index: 25; background: rgba(8, 11, 18, .4); }
  .side { padding: calc(14px + env(safe-area-inset-top, 0px)) 12px calc(12px + env(safe-area-inset-bottom, 0px)) calc(12px + env(safe-area-inset-left, 0px)); }
  .side-foot .mkt { max-width: calc(100% - 68px); } /* a long label ("Holiday · …") shortens instead of pushing the toggle out of the drawer */
  .side-foot .mkt .mkt-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .side-collapse { display: none; }
  .topbar { padding: 12px 16px; min-height: 60px; }
  .topbar .menu-btn { display: inline-flex; }
  .topbar h1 { font-size: 18px; }
  .topbar .sub { display: none; }
  .page { padding: 4px 16px 40px; }
  .cols-2, .cols-3, .cols-4 { grid-template-columns: minmax(0, 1fr); }
  /* flush (terminal): a slim bar, then the frame fills exactly the rest of the visible screen */
  body.flush .main { display: flex; flex-direction: column; height: 100vh; height: 100dvh; background: var(--ob-bg, var(--bg)); }
  body.flush .page { flex: 1; min-height: 0; height: auto; width: 100%; margin: 0; }
  body.flush .topbar.obbar {
    display: flex; flex: none; position: relative; gap: 8px; min-height: 0;
    height: calc(48px + env(safe-area-inset-top, 0px));
    padding: env(safe-area-inset-top, 0px) max(10px, env(safe-area-inset-right, 0px)) 0 max(6px, env(safe-area-inset-left, 0px));
    background: var(--ob-glass, var(--glass)); border-bottom-color: var(--ob-line, var(--line));
  }
  /* the title never gives way; when the row is tight the market pill's words go first */
  .obbar .ttl { gap: 9px; flex: none; }
  .obbar h1 { font-size: 17px; }
  .obbar .actions { flex: 1 1 auto; min-width: 0; gap: 6px; flex-wrap: nowrap; }
  .obbar .menu-btn { width: 40px; height: 40px; flex: none; }
  .obbar .mkt { height: 26px; padding: 0 10px; min-width: 0; overflow: hidden; }
  .obbar .mkt .mkt-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .obbar .mkt:empty { display: none; } /* until the first status arrives */
  .obbar .theme-toggle { flex: none; }
  .obbar .theme-toggle button::after { content: ''; position: absolute; inset: -7px -1px; } /* 40px tall touch target */
  .obbar .avatar-btn { width: 40px; height: 40px; padding: 0; flex: none; border: 0; border-radius: 50%; background: none; display: grid; place-items: center; cursor: pointer; transition: background .15s; }
  .obbar .avatar-btn:hover { background: var(--surface-3); }
  .obbar .avatar-btn .avatar { width: 30px; height: 30px; }
  .topbar.obbar .actions a.btn.unlock-btn { flex: none; height: 32px; padding: 0 11px; gap: 6px; border-radius: 10px; font-size: 13px; }
}
@media (max-width: 900px) and (max-height: 500px) {
  body.flush .topbar.obbar { height: calc(44px + env(safe-area-inset-top, 0px)); }
}
@media (max-width: 400px) {
  .obbar .mkt.open { display: none; } /* the LIVE pill beside the title already says it */
}
@media (max-width: 380px) {
  body.flush .topbar.obbar { gap: 6px; }
  .obbar .mkt-w { display: none; } /* "Opens 09:15" → "09:15" (the full label is the pill's tooltip) */
  .topbar.obbar .actions a.btn.unlock-btn { width: 32px; padding: 0; justify-content: center; } /* a locked preview's Unlock: the lock alone */
  .topbar.obbar .actions a.btn.unlock-btn span { display: none; }
}
@media (max-width: 356px) {
  .obbar .mkt { width: 26px; padding: 0; justify-content: center; }
  .obbar .mkt .mkt-text { display: none; }
}

/* ---------- locked preview (no plan: auth.Principal.Preview) ----------
   Every page opens as members have it, its sample data with every name and figure blurred (below); whatever needs
   a plan opens the Access Locked card as a dialog (OB.unlock). The menu marks the locked pages and carries an
   Unlock card, the top bar an Unlock button. */
.nav a .ic.nav-lock, .nav a:hover .ic.nav-lock, .nav a.on .ic.nav-lock { width: 14px; height: 14px; margin-left: auto; color: var(--ink-4); }
.nav a .live-pill:not([hidden]) + .ic.nav-lock { margin-left: 8px; }

.side-unlock { position: relative; display: flex; align-items: center; gap: 10px; padding: 10px 12px 10px 10px; border-radius: 14px; color: var(--ink);
  background: linear-gradient(135deg, var(--brand-soft), transparent 75%), var(--surface); border: 1px solid var(--brand-line);
  transition: border-color .2s, box-shadow .2s; }
.side-unlock:hover { border-color: var(--brand); box-shadow: 0 12px 26px -16px var(--brand); }
.side-unlock .su-ic { display: grid; place-items: center; width: 32px; height: 32px; flex: none; border-radius: 10px; color: #fff;
  background: linear-gradient(135deg, var(--brand), var(--brand-2)); box-shadow: 0 6px 14px -6px var(--brand), inset 0 1px 0 rgba(255, 255, 255, .22); }
.side-unlock .su-ic .ic { width: 16px; height: 16px; stroke-width: 2.1; }
.side-unlock .su-t { display: flex; flex-direction: column; flex: 1; min-width: 0; line-height: 1.3; }
.side-unlock .su-t b { font-size: 13px; font-weight: 700; }
.side-unlock .su-t em { font-style: normal; font-size: 11.5px; font-weight: 550; color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.side-unlock .su-go { color: var(--brand); transition: transform .2s var(--ease); }
.side-unlock:hover .su-go { transform: translateX(2px); }
@media (min-width: 901px) {
  body.rail .nav a .ic.nav-lock, body.rail .side-unlock .su-t, body.rail .side-unlock .su-go { display: none; }
  body.rail .side-unlock { justify-content: center; padding: 4px 0; border-color: transparent; background: none; box-shadow: none; }
}

/* the top bar's Unlock button: a soft shine crosses it every few seconds */
.btn.unlock-btn { position: relative; overflow: hidden; isolation: isolate; }
.btn.unlock-btn::after { content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, .36) 48%, transparent 66%); transform: translateX(-130%);
  animation: unlockShine 4.5s var(--ease) 1.2s infinite; }
@keyframes unlockShine { 0% { transform: translateX(-130%); } 30%, 100% { transform: translateX(130%); } }
/* it keeps its word on phones, where some pages' own top bar buttons shrink to icons */
.topbar .actions a.btn.unlock-btn { width: auto; padding: 0 14px; }
.topbar .actions a.btn.unlock-btn span { display: inline; }

/* the Access Locked card (OB.unlock) */
.lock-card { pointer-events: auto; position: relative; width: min(392px, 100%); padding: 32px 28px 24px; border-radius: 24px; text-align: center;
  background: var(--glass); backdrop-filter: blur(20px) saturate(1.5); -webkit-backdrop-filter: blur(20px) saturate(1.5);
  border: 1px solid var(--line-2); box-shadow: var(--shadow-pop); animation: lockIn .55s var(--ease) both; }
.lock-card::before { content: ''; position: absolute; inset: -1px; border-radius: inherit; padding: 1px; pointer-events: none;
  background: linear-gradient(160deg, var(--brand-line), transparent 38%, transparent 62%, var(--brand-line));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; }
@keyframes lockIn { from { opacity: 0; transform: translateY(16px) scale(.97); } }
.lock-badge { position: relative; display: grid; place-items: center; width: 62px; height: 62px; margin: 0 auto 18px; border-radius: 20px; color: #fff;
  background: linear-gradient(135deg, var(--brand), var(--brand-2)); box-shadow: 0 16px 34px -14px var(--brand), inset 0 1px 0 rgba(255, 255, 255, .28); }
.lock-badge .ic { width: 26px; height: 26px; stroke-width: 2; }
.lock-badge::before, .lock-badge::after { content: ''; position: absolute; inset: -7px; border-radius: 25px; border: 1.5px solid var(--brand-line);
  animation: lockRing 2.8s var(--ease) infinite; }
.lock-badge::after { animation-delay: 1.4s; }
@keyframes lockRing { 0% { opacity: .9; transform: scale(.92); } 75%, 100% { opacity: 0; transform: scale(1.3); } }
.lock-card h2 { font-size: 24px; font-weight: 780; letter-spacing: -.035em; }
.lock-card > p { margin-top: 8px; color: var(--ink-2); font-size: 14.5px; line-height: 1.55; text-wrap: balance; }
.lock-card > p.lock-live { display: inline-flex; align-items: center; gap: 8px; margin-top: 14px; padding: 5px 12px 5px 10px; border-radius: 99px;
  background: var(--bull-soft); color: var(--bull); font-size: 12.5px; font-weight: 650; line-height: 1.4; text-wrap: initial; }
.lock-card > p.lock-live.pre { background: var(--amber-soft); color: var(--amber); }
.lock-card > p.lock-live[hidden] { display: none; }
.lock-go { margin-top: 22px; height: 50px; border-radius: 14px; font-size: 15.5px; }
.lock-go .ic:last-child { transition: transform .2s var(--ease); }
.lock-go:hover .ic:last-child { transform: translateX(3px); }
.lock-card > p.lock-price { margin-top: 12px; font-size: 12.5px; color: var(--ink-3); }
.lock-price b { color: var(--ink); font-size: 13px; font-weight: 700; }
/* as a dialog (OB.unlock) */
.overlay.unlock { z-index: 85; }
.overlay.unlock .lock-card { background: var(--surface); backdrop-filter: none; -webkit-backdrop-filter: none; }
.lock-x { position: absolute; top: 12px; right: 12px; }

@media (max-width: 900px) {
  .lock-card { padding: 28px 22px 20px; border-radius: 22px; }
  .lock-card h2 { font-size: 22px; }
}

/* a locked preview's sample data: every figure (OB.blurFigures wraps them in <ob-n>) and every name (.ob-blur)
   blurred. The glyphs are transparent and only their blurred shadow is drawn, in the text's own colour, at least
   6px wide, so even small text can't be read (the terminal's own copy: tools/terminal_locked.css) */
ob-n, ob-n *, .ob-blur, .ob-blur * { -webkit-text-fill-color: transparent !important;
  text-shadow: 0 0 max(.7em, 6px) currentColor, 0 0 max(.7em, 6px) currentColor, 0 0 max(.7em, 6px) currentColor !important; }
ob-n { font: inherit; letter-spacing: inherit; }
.ob-svgfig { filter: blur(3px); }

