/* ==========================================================================
 * src/css/shell.css — shared page shell: app frame, docked sidebar slot, top bar.
 * Single source of truth. Pages must NOT redefine .vx-app / .vx-dock / .vx-head / .vx-title /
 * .vx-burger / .vx-bar / .vx-icons / .vx-left (page CSS only styles its own content).
 *
 * LAYOUT MODES (width-based, never orientation-based — see src/js/shell/viewport.js)
 *   wide     >= 1025px : 264px docked sidebar + centred top bar            (the original desktop design, unchanged)
 *   compact  <= 1024px : hamburger + slide-out drawer, top bar re-flowed for phones / tablets
 *
 * Markup contract (header):
 *   <header class="vx-head [vx-tl]">
 *     <button class="vx-burger" id="vx-burger">..</button>  <span class="vx-bar"></span>   (compact only)
 *     <div class="vx-left">..</div>                                                        (wide only, optional)
 *     <div class="vx-title">Title</div>
 *     <nav class="vx-icons"> <a>bell</a> </nav>
 *   </header>
 *   .vx-tl = title left-aligned next to the burger in compact mode (default is centred).
 * ========================================================================== */

:root {
  --vx-head-h: 60px;
  --vx-head-reserve: 180px;   /* space kept free on each side of a centred title (icons / breadcrumb) */
  --vx-dock-w: 264px;
}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
  -webkit-text-size-adjust: 100%;   /* stops iOS inflating text after rotation — a classic "sizing not settled" bug */
  text-size-adjust: 100%;
}
html, body {
  width: 100%;
  min-height: 100%;
  background: var(--vx-page, var(--vx-bg, #fff));
  color: var(--vx-text, #2f2f2f);
  font-family: 'Poppins', system-ui, sans-serif;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;        /* no rubber-band gap above the top bar */
}
@supports not (overflow: clip) { html { overflow-x: hidden; } }   /* body must stay non-scrolling or the sticky bar breaks */
button { font-family: inherit; color: inherit; background: none; border: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
a { color: inherit; text-decoration: none; }
svg { flex: none; }
[hidden] { display: none !important; }

/* ---------- app frame ---------- */
.vx-app { display: flex; min-height: 100vh; min-height: 100dvh; }
.vx-dock { position: sticky; top: 0; height: 100vh; height: 100dvh; align-self: flex-start; flex: none; }
.vx-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.vx-content { flex: 1 1 auto; display: flex; flex-direction: column; }
.vx-panel { display: flex; flex-direction: column; }

/* ---------- top bar (wide) ---------- */
.vx-head {
  position: sticky; top: 0; z-index: 20;
  height: var(--vx-head-h); flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--vx-bg, #fff);
  border-bottom: 1px solid var(--vx-divider, #dcdcdc);
}
.vx-title {
  min-width: 0;
  max-width: calc(100% - 2 * var(--vx-head-reserve));
  font-size: clamp(16px, 1.12vw, 19px);   /* ≈17px at a 1512px MacBook viewport, never shrinks below 16px */
  font-weight: 400;
  color: var(--vx-text, #2f2f2f);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  pointer-events: none;
}
.vx-left {
  position: absolute; left: 24px; top: 0; height: 100%;
  display: flex; align-items: center; gap: 4px;
  font-size: 15px; color: var(--vx-title, #3f3f3f);
}
.vx-left svg { width: 15px; height: 15px; }
.vx-burger, .vx-head .vx-bar { display: none; }
.vx-icons {
  position: absolute; right: 32px; top: 0; height: 100%;
  display: flex; align-items: center; gap: 22px;
}
.vx-icons a { display: flex; align-items: center; color: var(--vx-text, #2f2f2f); }
.vx-icons svg { width: 20px; height: 20px; }

/* ---------- collapsible docked sidebar (wide only) ----------
 * html.vx-dock-off : the 264px dock slides off to the left, the page widens to fill the space, and the top bar shows
 * [fries button + logo] at its left (injected by vertx-sidebar.js) to bring it back. See VertxSidebar.setCollapsed(). */
.vx-ex { display: none; }
@media (min-width: 1025px) {
  .vx-left { transition: left .3s cubic-bezier(.22,.8,.24,1); }
  .vx-dock { margin-left: 0; transition: margin-left .3s cubic-bezier(.22,.8,.24,1), visibility 0s; }
  html.vx-dock-off .vx-dock { margin-left: calc(-1 * var(--vx-dock-w)); visibility: hidden; transition: margin-left .3s cubic-bezier(.22,.8,.24,1), visibility 0s .3s; }
  .vx-ex {
    position: absolute; left: 12px; top: 0; height: 100%;
    display: flex; align-items: center; gap: 6px;
    opacity: 0; visibility: hidden; pointer-events: none;
    transition: opacity .2s ease, visibility 0s .2s;
  }
  html.vx-dock-off .vx-ex { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity .25s ease .12s, visibility 0s; }
  .vx-ex-btn { width: 40px; height: 40px; border-radius: 8px; display: flex; align-items: center; justify-content: center; color: var(--vx-text, #2f2f2f); }
  .vx-ex-btn:hover { background: var(--vx-hover, #f4f4f4); }
  .vx-ex-btn:focus-visible { outline: 2px solid #BF0016; outline-offset: 2px; }
  .vx-ex-logo { display: flex; align-items: center; }
  .vx-ex-logo img { height: 26px; width: auto; display: block; }
  html.vx-dock-off .vx-left { left: 212px; transition: left .3s cubic-bezier(.22,.8,.24,1); }   /* keep the page's own left item clear of the logo */
  html.vx-dock-off { --vx-head-reserve: 300px; }
}
@media (prefers-reduced-motion: reduce) { .vx-dock, .vx-ex, .vx-left { transition: none !important; } }

/* ==========================================================================
 * COMPACT MODE  (keep this breakpoint identical to VxViewport.QUERY in viewport.js)
 * ========================================================================== */
@media (max-width: 1024px) {
  :root { --vx-head-reserve: 100px; }

  .vx-dock, .vx-left { display: none !important; }

  .vx-head {
    justify-content: flex-start;
    padding-inline: max(8px, env(safe-area-inset-left)) max(8px, env(safe-area-inset-right));
  }
  .vx-burger {
    display: flex; flex: none; align-items: center; justify-content: center;
    width: 44px; height: 44px;            /* 44px = minimum comfortable touch target */
  }
  .vx-head .vx-bar { display: none; }   /* divider removed: title sits right beside the fries icon */

  /* title: always left-aligned, right after the fries icon */
  .vx-head .vx-title, .vx-head.vx-tl .vx-title {
    position: static; flex: 1 1 auto; margin: 0 0 0 2px;
    max-width: none;
    font-size: 18px; font-weight: 500; text-align: left;
  }

  .vx-icons { position: static; margin-left: auto; flex: none; gap: 0; }   /* in the flow: the title adapts to however many icons exist */
  .vx-icons a { width: 44px; height: 44px; justify-content: center; }
}

/* very small phones: tighten the reserve so a centred title still has room */
@media (max-width: 359px) {
  :root { --vx-head-reserve: 96px; }
  .vx-title { font-size: 16px; }
  .vx-head.vx-tl .vx-title { font-size: 16.5px; }
}


/* ==========================================================================
 * TOP-BAR ICONS: one size, one gap, on every page.
 * Bell (<a>), theme button and fullscreen button are injected by different scripts with their own margins; this block is the
 * single authority. Every direct child is the same square hit-box with its glyph centred, margins are zeroed, and the spacing
 * comes only from the bar's gap. (Specificity beats .vx-theme-btn / .vx-fs-btn in theme.css.)
 * ========================================================================== */
.vx-icons { gap: 6px; }
.vx-icons > a, .vx-icons > button {
  position: relative; flex: none; display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; margin: 0; padding: 0; border-radius: 50%;
}
.vx-icons > a svg, .vx-icons > button svg { width: 20px; height: 20px; }
@media (max-width: 1024px) {
  .vx-icons { gap: 0; }
  .vx-icons > a, .vx-icons > button { width: 44px; height: 44px; }
}
