/* ============================================================================
   shell.css — the chrome every non-graph page wears
   ----------------------------------------------------------------------------
   The marketplace is a full-bleed map: its chrome is a set of floating panels
   pinned over a canvas, and it does not load this file. A document page is the
   other shape — it scrolls, it has a top and a bottom — so the same vocabulary
   is restated here as a bar and a rule instead of as panels.

   Nothing below invents a colour, blur, shadow, radius or type value. Every
   declaration resolves through src/shared/tokens.css, which means the
   [data-theme="dark"] block in tokens-dark.css re-points all of it for free.

   Load order: tokens.css, tokens-dark.css, this file, then the page's own
   stylesheet, then any module stylesheet.

   Contract with the marketplace (deliberate, not incidental):
     · storage key      cognia_theme_v1, values "light" / "dark"
     · meta theme-color #FFF7F0 light · #171310 dark
     · the tile dispatches `theme:toggle` and implements nothing
     · the commit sets [data-theme-switching] on <html> for two frames
   shell.js is the only listener, exactly as marketplace.js is on that page.
   ========================================================================== */

/* The site nav lives in one file and is mounted by shell.js into .shell-brand,
   so a page that already wears this stylesheet needs no markup change to get
   it. @import must precede every rule below, which is why it is here rather
   than beside the header block further down. */
@import url("nav.css");

/* -- wordmark face (local only, no CDN; same declaration marketplace.css makes,
      re-stated because a page may load this file without that one) ---------- */
@font-face{
  font-family:Jost;
  src:url("../../assets/fonts/jost.ttf") format("truetype");
  font-weight:100 900; font-style:normal; font-display:swap;
}

/* -- base ------------------------------------------------------------------
   The marketplace pins `html,body{overflow:hidden}` because the graph owns the
   viewport. A document page must scroll, so that rule is the one thing not
   carried over. */
*{ box-sizing:border-box; }
html{ background:var(--paper); }
/* A column, so a short page — a not-found state, an empty profile — still puts
   its footer on the floor instead of halfway up the viewport. */
body{
  margin:0; min-height:100dvh;
  display:flex; flex-direction:column;
  background:var(--paper); color:var(--ink);
  font-family:var(--font-body);
  -webkit-text-size-adjust:100%;
}
.shell-main{ flex:1 0 auto; }
.shell-head,.shell-foot{ flex:0 0 auto; }
button,input,select,textarea{ font:inherit; color:inherit; }
button{ cursor:pointer; }
[hidden]{ display:none !important; }
.mono{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; }
.muted{ color:var(--graphite); }
.sr-only{ position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }

/* -- header ----------------------------------------------------------------
   A full-bleed glass bar on the sidebar's ground (--paper-70 under
   --blur-sidebar), closed by the same warm hairline the sidebar's .head uses.
   Sticky rather than fixed: the page below it is a document, and a fixed bar
   would need every section to carry scroll-margin for no gain. */
.shell-head{
  position:sticky; top:0; z-index:40;
  display:flex; align-items:center; gap:var(--sp-11);
  padding:var(--sp-9) var(--sp-16);
  background:var(--paper-70);
  -webkit-backdrop-filter:var(--blur-sidebar); backdrop-filter:var(--blur-sidebar);
  /* §9 — remove the full-width header divider; the cognia dropdown is the head's
     only chrome now. */
}
/* the sidebar's back-link slot, at its size and its two colours */
.shell-back{
  font-size:var(--fs-md); color:var(--graphite); text-decoration:none;
  padding:var(--sp-3) var(--sp-4); border-radius:var(--r-7);
  transition:color var(--dur-140) var(--ease);
}
.shell-back:hover{ color:var(--brand); }

/* `position:relative` is the nav's anchor: in a sticky bar the panel floats
   under the brand rather than growing the bar, which would shove the document
   the bar is stuck to. It is the only line the nav adds to the shell's chrome. */
.shell-brand{ display:flex; align-items:center; gap:var(--sp-8); min-width:0;
  position:relative; }
.shell-brand img{ width:26px; height:26px; border-radius:var(--r-6); flex:0 0 auto;
  object-fit:contain; }
/* the marketplace's wordmark, one step down: 19px there sits beside a 30px
   logo tile in a 296px column; 17px sits beside a 26px tile in a bar. */
.shell-wordmark{
  font:300 17px/1 Jost, var(--font-display);
  letter-spacing:.28em; color:var(--brand); padding-left:.14em;
}

.shell-head .spacer{ flex:1 1 auto; }

/* the dark-mode tile, at the tile row's exact metrics: 38px, radius 11,
   --paper-72 under --blur-tile, a 1px --brand-20 edge, --sh-3-tile. */
.shell-tile{
  width:38px; height:38px; flex:0 0 auto;
  display:grid; place-items:center; padding:0;
  border-radius:var(--r-11); cursor:pointer;
  color:var(--brand); background:var(--paper-72); text-decoration:none;
  -webkit-backdrop-filter:var(--blur-tile); backdrop-filter:var(--blur-tile);
  border:1px solid var(--brand-20); box-shadow:var(--sh-3-tile);
  transition:background var(--dur-140) var(--ease),
             border-color var(--dur-140) var(--ease);
}
.shell-tile:hover{ background:var(--brand-14); }
.shell-tile svg{ width:18px; height:18px; display:block; }
/* two glyphs in one cell so the state swap cross-fades on the row's 140ms
   budget instead of cutting — the marketplace's .tile-ic, unchanged. */
.shell-tile .tile-ic{ display:grid; place-items:center; width:18px; height:18px; }
.shell-tile .tile-ic > svg{ grid-area:1/1;
  transition:opacity var(--dur-140) var(--ease), transform var(--dur-140) var(--ease); }
.shell-tile .ic-sun{ opacity:0; transform:scale(.72) rotate(-16deg); }
html[data-theme="dark"] .shell-tile .ic-sun{ opacity:1; transform:none; }
html[data-theme="dark"] .shell-tile .ic-moon{ opacity:0; transform:scale(.72) rotate(16deg); }

/* -- footer ----------------------------------------------------------------
   One protocol line, in the netline's size and colour. */
.shell-foot{
  margin-top:var(--sp-20);
  padding:var(--sp-15) var(--sp-16) calc(var(--sp-17) + env(safe-area-inset-bottom,0px));
  border-top:1px solid var(--border);
  font-family:var(--font-mono); font-size:var(--fs-sm);
  color:var(--graphite); letter-spacing:var(--ls-01);
}
.shell-foot b{ color:var(--ink); font-weight:var(--fw-semibold); }
.shell-foot .dot{ color:var(--brand-45); padding:0 var(--sp-2); }

/* -- phone -----------------------------------------------------------------
   The bar stays; it only tightens. */
@media (max-width:768px){
  .shell-head{ padding:var(--sp-7) var(--sp-9); gap:var(--sp-7); }
  .shell-brand img{ width:22px; height:22px; }
  .shell-wordmark{ font-size:15px; letter-spacing:.22em; }
  .shell-foot{ padding:var(--sp-13) var(--sp-9) calc(var(--sp-15) + env(safe-area-inset-bottom,0px));
    font-size:var(--fs-xs-p); }
}

/* -- accessibility fallbacks (the marketplace's two, verbatim) ------------- */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{ animation:none !important; transition-duration:.01ms !important; }
}
@media (prefers-reduced-transparency: reduce){
  .shell-head{ background:var(--paper); backdrop-filter:none; -webkit-backdrop-filter:none; }
}
[data-theme="dark"] .shell-tile{ color:var(--brand); }
@media (prefers-reduced-transparency: reduce){
  [data-theme="dark"] .shell-head{ background:var(--surface); }
}

/* -- the switch itself -----------------------------------------------------
   Theming is instant by design, not a crossfade. shell.js sets this attribute
   for the commit and drops it two frames later; transitions only, so running
   animations are not restarted. Identical to the marketplace's rule. */
html[data-theme-switching],
html[data-theme-switching] *,
html[data-theme-switching] *::before,
html[data-theme-switching] *::after{ transition:none !important; }
