/* shell.css — the Cheoma app shell, defined once.
   ------------------------------------------------------------------
   app/index.html carries this shell as inline styles on a dc-runtime
   template ({{ themeVars }} + sc-for loops). The four static pages
   (base / robinhood / sonic / optimizer) ship raw, with no build step,
   so they cannot include a template partial. This file is the single
   definition they all reference: the same vertical <nav> column (the
   "sidebar"), the same spacing, type, colours and mobile behaviour as
   app/index.html.

   Token values below are copied verbatim from THEMES.light in
   app/index.html so the shell resolves to the same palette. They are
   scoped to .app-shell (mirroring the app, where themeVars are emitted
   on the single outer wrapper) so the pages' own tokens are untouched.

   mobile.css?v=2 and mobile.js?v=2 are loaded unchanged. Their drawer
   mechanics key off `aside` / `#mobile-nav-toggle` / `body.nav-open`,
   which this markup supplies; the two padding hooks in mobile.css match
   *inline* styles, so the class-based equivalents live at the bottom of
   this file. */

.app-shell {
  /* palette — app/index.html THEMES.light */
  --bg: #F5F4F0; --bgFade: rgba(245,244,240,.86);
  --card: #FFFFFF; --card2: #F7F6F3;
  --line: rgba(16,18,24,.07); --line2: rgba(16,18,24,.055); --hover: rgba(16,18,24,.04);
  --text: #14161C; --sub: #4B505C; --muted: #5F6470;
  --gold: #654810; --goldSolid: #C9973F; --goldSoft: rgba(224,181,101,.18);
  --teal: #0E7A6E; --tealSolid: #0E9384; --tealSoft: rgba(14,147,132,.10);
  --neg: #B0553C; --negSoft: rgba(176,85,60,.10);
  --btn: #14161C; --btnText: #FFFFFF; --btnHover: #2A2E38;
  --hero: linear-gradient(155deg,#14161C,#232734);
  --promo: linear-gradient(160deg,#FBF1DF,#F5E6CB); --promoLine: rgba(201,151,63,.28);

  /* shell root — app/index.html line 29 */
  background: var(--bg);
  color: var(--text);
  font-family: Geist,-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,Arial,sans-serif;
  min-height: 100vh;
  display: flex;
}

/* ---------- box model ----------
   app/index.html ships no global border-box reset, so its 238px sidebar
   actually renders 275px wide (238 + 22/18 padding + 1px border) and its
   hamburger 42px. The four pages do carry a border-box reset, which would
   leave the sidebar 36px narrower than the app's — so the shell elements opt
   back out. This is scoped to the sidebar (shell markup only) and to the
   toggle; page content keeps its existing border-box sizing. */
.app-aside, .app-aside * { box-sizing: content-box; }
/* The hamburger is shell markup, so it must not depend on the page having a
   reset: base.html ships `*{margin:0;padding:0}`, the dc-runtime pages do not,
   and without this the UA's button padding (1px 6px) shows through and the
   control renders 54x44 instead of the app's 42x42. */
#mobile-nav-toggle { box-sizing: content-box; padding: 0; }

/* ---------- vertical nav column ("sidebar") ---------- */
.app-aside {
  flex: none;
  width: 238px;
  position: sticky;
  top: 0;
  align-self: flex-start;
  /* content-box (see the box-model note above) means the 22px top + 22px bottom
     padding is ADDED to this height. At height:100vh the column therefore ran 44px
     past the bottom of the viewport, and the promo card pinned to its bottom by
     margin-top:auto sat below the fold with no way back: overflow-y:auto cannot
     scroll a box that is itself taller than the viewport. Subtracting the padding
     puts the whole column — and the bottom of the promo card — inside the fold
     (measured on production at 1440x900 and 390x844). */
  height: calc(100vh - 44px);
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 22px 18px;
  background: var(--card);
  border-right: 1px solid var(--line);
  overflow-y: auto;
}

.app-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 8px;
  color: var(--text);
  text-decoration: none;
}
.app-logo-text { font-weight: 600; font-size: 16.5px; letter-spacing: -.02em; }

.app-nav { display: flex; flex-direction: column; gap: 3px; }

.app-nav-link {
  display: flex;
  align-items: center;
  padding: 10px 13px;
  border-radius: 11px;
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
  background: transparent;
  text-decoration: none;
  border: 0;
}
.app-nav-link:hover { background: var(--line2); color: var(--muted); }
.app-nav-link.is-active { color: var(--text); background: var(--hover); }

.app-div { height: 1px; background: var(--line2); }

.app-promo {
  margin-top: auto;
  border-radius: 16px;
  padding: 16px;
  background: var(--promo);
  border: 1px solid var(--promoLine);
}
.app-promo-title { font-size: 13.5px; font-weight: 600; margin-bottom: 4px; }
.app-promo-body { font-size: 12.5px; line-height: 1.5; color: var(--muted); }

/* ---------- main column ---------- */
.app-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  max-width: none;
  margin: 0;
  padding: 0;
}

/* L2 sub-logo under the Cheoma wordmark (designer 2026-09-29: "logos for each
   page … as a small sub logo, under Cheoma logo") + the chain chip in the page
   header. The mark is a colour dot + chain name: no third-party logo art is
   vendored on this host, so real L2 logo files can drop straight into .l2dot. */
.app-logo-stack { display: flex; flex-direction: column; gap: 1px; line-height: 1.15; }
.app-logo-l2 {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: 'Geist Mono', ui-monospace, Menlo, monospace;
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted);
}
.l2dot { width: 6px; height: 6px; border-radius: 50%; background: var(--goldSolid, #C9973F); flex: none; }
.app-chain-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: 999px;
  border: 1px solid var(--line, rgba(16,18,24,.07)); background: var(--card, #FFFFFF);
  font-size: 12.5px; font-weight: 500; color: var(--sub, #4B505C);
}

.app-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 20px;
  padding: 16px 28px;
  background: var(--bgFade);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line2);
}
.app-head-lead { display: flex; align-items: center; gap: 12px; min-width: 0; }
.app-title { font-size: 17px; font-weight: 600; letter-spacing: -.02em; }
.app-subtitle { font-size: 12.5px; color: var(--muted); }
.app-head-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }

.app-content {
  padding: 26px 28px 56px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}
/* the pre-deposit pages were a 760px centred column, the optimizer an 860px one;
   the column width is kept, now aligned inside the shell as in the app */
.app-content--narrow { max-width: 760px; }
.app-content--mid { max-width: 860px; }

/* ---------- mobile padding ----------
   mobile.css tightens padding by matching the app's *inline* styles
   (header[style*="padding:16px 28px"], div[style*="padding:26px 28px"]).
   Those hooks do not fire on app/index.html either — its dc runtime rewrites
   the style attribute — so the app renders its desktop 16px/28px and
   26px/28px/56px padding at every width. This shell therefore mirrors nothing
   here, and measures identically to the app at 390x844 (asserted in
   shell-render-check.js). mobile.css's element/id rules — hamburger, drawer,
   backdrop, body.nav-open — still apply unchanged. */
