/* ════════════════════════════════════════════════════════════════════
   KHIO LIFE APP SHELL — structural half of /js/shared/life-shell.js.
   Loaded by recipes.html (/add-ons) and connections.html (/connections).
   James 2026-07-27.

   Everything here is inert until life-shell.js puts `khio-shelled` on <html>,
   which it only does for a signed-in, top-level, desktop visit. A public
   marketing visit, the ?embed=1 iframe and phones all render exactly as they
   did before this file existed.

   Only the rail's geometry lives here. premium.css owns those rules for the
   other ten Life pages, but it also restyles .card / .btn-primary / body copy,
   which would fight these two pages' bespoke .rc-* / .cx-* design — so the
   handful of rules the rail actually needs are restated instead of pulling the
   whole stylesheet in. sidebar-life.css (loaded by life-shell.js) still owns
   every bit of the rail's own paint.
   ════════════════════════════════════════════════════════════════════ */

/* Canonical universal-dark tokens. Source of truth is the top of premium.css;
   this is the third copy, alongside cal-ai-life.css, for the same reason —
   these pages don't load premium.css. Keep all three in sync, and alias to
   these instead of writing a new dark hex into a page. */
:root {
    --khio-dark-bg: #121212;
    --khio-dark-surface: #1d1d1d;
    --khio-dark-surface-2: #282828;
    --khio-dark-text: #f4f4f5;
    --khio-dark-text-soft: rgba(255,255,255,.66);
    --khio-dark-text-mut: rgba(255,255,255,.55);
    --khio-dark-border: rgba(255,255,255,.12);
    --khio-dark-track: rgba(255,255,255,.08);
    --khio-dark-accent: #f4f4f5;
    --khio-dark-on-accent: #121212;
}

/* The mount div is in both pages' markup unconditionally so shared-nav.js can
   find it the moment it parses. Unshelled it stays empty, so keep it out of
   flow entirely. */
#khio-sidebar { display: none; }

html.khio-shelled {
    /* Matches premium.css's --sidebar-width and dashboard.html's --sidebar-w,
       so the rail is the same width here as on every other Life page. */
    --sidebar-width: 300px;
}

html.khio-shelled #khio-sidebar { display: block; }

/* position/width/height/flex normally come from premium.css's .khio-sidebar
   block. sidebar-life.css assumes they are already applied — it only paints. */
html.khio-shelled .khio-sidebar {
    position: fixed;
    left: 0;
    top: 0;
    width: var(--sidebar-width);
    height: 100vh;
    display: flex;
    flex-direction: column;
    z-index: 50;
}

/* Padding rather than a margin on the content wrapper: both pages centre their
   own `max-width:1120px; margin:0 auto` column, so padding the body lets that
   column re-centre itself in the space left over, with no change to either
   page's own layout rules. */
html.khio-shelled body { padding-left: var(--sidebar-width); }

/* The beach hero banner (body::before, /images/landing/bg3a.jpg) is marketing
   art. applyColorScheme in shared-nav.js flattens body's own cream gradient to
   the app scheme colour but does NOT touch pseudo-elements, so the photo would
   be left floating on a flat app background — and on matte black it reads as a
   bright band across the top. */
html.khio-shelled body::before { display: none; }

/* Canvas paint, on the first frame. applyColorScheme in shared-nav.js flattens
   body to the app scheme colour, but it only lands once shared-nav has loaded —
   until then the page still shows its own marketing cream + noise + fixed
   gradient. In light both are warm off-white and the swap is invisible; in dark
   it is a full-brightness flash of cream before the page goes matte, so the
   colour flips here instead. This file is a render-blocking <link> in <head>
   and the gate that sets .khio-shelled is inline above it, so both are settled
   before anything paints. */
html.khio-shelled body { background-image: none !important; }
html.khio-shelled[data-theme="dark"],
html.khio-shelled[data-theme="dark"] body { background-color: var(--khio-dark-bg) !important; }

/* A resize below 1024 after load: the gate in life-shell.js has already run and
   won't re-run, so hand the page back its own chrome rather than leaving a
   300px gutter with nothing in it and no visible way out.

   `!important` is load-bearing, and this rule did nothing without it. Each page
   hides its own bar with `html.khio-shelled .cx-top { display: none }` in its
   inline <style>, which is the SAME specificity (0,2,1) as the line below and
   comes LATER in the document than this <link> — so the hide won every time.
   The result was the exact dead end this block exists to prevent: drag a
   signed-in window under 1024px and the rail went, the bar never came back, and
   there was no navigation at all until you reloaded. A media query adds no
   specificity, so nothing short of !important can carry it. Found and fixed
   2026-08-01. `.rx-top` (/add-ons/:slug) was also missing from the list. */
@media (max-width: 1023px) {
    html.khio-shelled #khio-sidebar { display: none; }
    html.khio-shelled body { padding-left: 0; }
    html.khio-shelled .rc-top,
    html.khio-shelled .rx-top,
    html.khio-shelled .cx-top { display: flex !important; }
}
