/* Kozak on a phone -- the SHELL (header, drawer, account menu, globals).
   Owner: shell area. Spec: docs/superpowers/specs/2026-10-01-kozak-phone-layout-design.md

   Linked from base.html with media="(pointer: coarse) and (max-width: 960px)"
   (D1/D2) and AFTER the head block, so: no @media wrapper is needed here, a
   desktop browser never applies a byte of this file, and it loads after app.css,
   lookup.css and every sub-app inline <style>. The area files (harness.css,
   matrix.css, ...) are linked AFTER this one, so they win ties against it.

   Never overflow-x:hidden/clip to make overflow go away (D8). */

/* ---- Globals (audit SH-6 / SH-7) ------------------------------------------ */

/* iOS inflates text on rotation to landscape without this. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
/* app.css's 100vh is the LARGE viewport on iOS, so a short page (/lookup)
   scrolls by the height of the URL bar. */
body{min-height:100svh}

/* iOS Safari zooms the whole page on focus of any field under 16px. !important
   on purpose: sub-app inline <style> blocks and the vendor tabulator CSS size
   their own fields with higher specificity. NOT maximum-scale=1 in the viewport
   meta instead -- Android honours it and it kills pinch-zoom, which the wide
   tables need. */
:root :is(input:not([type=checkbox],[type=radio],[type=range],[type=file],[type=hidden],[type=button],[type=submit],[type=reset],[type=color],[type=image]),select,textarea){font-size:16px !important}

/* No double-tap-to-zoom delay/zoom on controls (fast LP ticking). */
a,button,summary,label,select,input,textarea{touch-action:manipulation}

/* 18px gutters are too much at 360. `:root` bumps specificity past the
   same-specificity rules in sub-app inline <style> blocks. */
:root main{padding:12px}
:root .toolbar{padding:10px 12px}

/* Shared controls to 44px (D9) through padding + line-height, NOT min-height:
   an inline-block with a min-height pins its text to the top of the box (the
   PROD-confirm Cancel is an a.ghost). .ghost/.tab carry a 1px border, .primary
   none: 20 + 2*11 + 2 = 44 and 20 + 2*12 = 44. */
:root .ghost,:root .tab{padding-top:11px;padding-bottom:11px;line-height:20px;font-size:14px}
:root .primary{padding-top:12px;padding-bottom:12px;line-height:20px;font-size:14px}
/* Vertical padding only grows the layout box of an inline-block. :where() keeps
   this at zero specificity, so any area rule that sets its own display wins. */
:where(a.ghost,a.tab,a.primary){display:inline-block}

/* ---- Header (SH-2 / SH-3 / SH-4) ------------------------------------------ */

/* 44 (controls) + 2*6 (padding) + 1 (border) = 57. --hdr also offsets
   .qmtoasts/.navsticky in app.css; areas may use it for sticky table heads. */
:root{--hdr:57px}
header.app{gap:8px;padding:6px 12px;flex-wrap:wrap;row-gap:4px}
header.app .spacer{display:none}
/* h1 is a flex box so the link is a shrink-wrapped flex item, NOT a full-width
   block: that would turn the empty middle of the header into a "go to section
   root" tap zone. 20 + 2*12 = 44, no inline line-box slop. */
header.app h1{flex:1 1 0;min-width:0;display:flex;align-items:center;font-size:17px;line-height:20px}
header.app h1 a.sectionhome{display:block;min-width:0;padding:12px 0;overflow-wrap:break-word}
header.app .navtoggle{flex:none;width:44px;height:44px;padding:0;font-size:20px;line-height:1}
/* Theme -> icon-only (D14). The words stay in the DOM as the accessible name;
   font-size:0 hides them and the glyph comes back at its own size. */
header.app .themebtn{flex:none;width:44px;height:44px;padding:0;font-size:0;line-height:1}
header.app .themebtn::before{content:"\25D0";font-size:20px}
/* The avatar summary was a 26px target. */
header.app .acct{flex:none}
header.app .acct>summary{display:grid;place-items:center;width:44px;height:44px}
header.app .acct>summary .avatar{width:34px;height:34px;font-size:12px}

/* header_actions (only onboarding fills it today: sync note + Refresh) wrap to
   a SECOND ROW in portrait -- they pushed Theme off-screen (page 424px wide at
   360). Landscape fits on one row. Row 1 = toggle / title / avatar / theme;
   the ::after is a zero-height full-width break, row 2 = the actions. */
@media (max-width:600px){
  /* row-gap 0 + a margin on row 2: the zero-height break is a flex LINE of its
     own, so a row-gap would be paid twice (header 109 instead of 105). */
  header.app:has(>.spacer+:not(.acct):not(.themebtn)){row-gap:0}
  header.app>.spacer~:not(.acct):not(.themebtn){order:2;margin-top:4px}
  /* top-aligned so a 44px button's line box is 44, not 44 + baseline slop */
  header.app>.spacer~:not(.acct):not(.themebtn) .ghost{vertical-align:top}
  header.app:has(>.spacer+:not(.acct):not(.themebtn))::after{content:"";order:1;flex-basis:100%;height:0}
  :root:has(header.app>.spacer+:not(.acct):not(.themebtn)){--hdr:105px}
}

/* ---- Account menu (SH-5) -------------------------------------------------- */

/* Anchored to the sticky header (its containing block once .acct is static),
   not to the avatar's right edge -- it opened at left:-22px at 360. Right
   aligned and capped, so landscape gets a menu, not an 820px strip. */
header.app .acct{position:static}
header.app .acctpop{top:calc(100% + 4px);right:12px;left:auto;box-sizing:border-box;
  width:min(340px,calc(100vw - 24px));min-width:0;max-width:none}
header.app .acctitem{padding:12px;font-size:16px}

/* ---- PROD signal in the sticky header (D14 / SH-8) ------------------------ */

/* The red banner scrolls away on a 4000px battery list; the header doesn't.
   Text lives here, not in the HTML, so no page string count changes. The
   harness/history/grid views all carry .prodbanner; other areas extend this
   with their own PROD state. */
body:has(.prodbanner) header.app{box-shadow:inset 0 -3px 0 #b42318}
body:has(.prodbanner) header.app a.sectionhome::after{content:"PROD";display:inline-block;margin-left:8px;
  padding:2px 8px;border-radius:999px;background:#b42318;color:#fff;font-size:11px;font-weight:700;
  line-height:16px;letter-spacing:.04em;vertical-align:top}

/* ---- Drawer (D5 / D6 / SH-1) ---------------------------------------------- */

/* Off-canvas, closed on every load, html.nav-open is never stored (the JS is in
   base.html's head). z-index: backdrop 150 / drawer 160 sit above toasts and
   #reqcard-mount (60) and the tabulator loading alert (100); the opening
   curtain (#kzsplash, 200) stays on top with pointer-events:none.
   ★ The HEADER stays ABOVE both while the drawer is open (170), and the drawer
   starts UNDER it (top:var(--hdr)). With the drawer at top:0 its 'Kozak' brand
   link sat exactly where the ☰ is, so the natural second tap on ☰ to close it
   NAVIGATED to / instead (-> /p/AC: product silently switched on a PROD page).
   Now that tap hits the ☰ itself; any other header tap (title, avatar, theme)
   lands on a header control and the capture listener closes + consumes it, so
   nothing under the finger acts. The PROD pill stays visible and undimmed.
   This relies on --hdr == the header's real height (57, or 105 for the
   portrait 2-row onboarding header) -- if a header grows past --hdr it covers
   the top of the drawer, so keep the two in step. */
html.nav-open header.app{z-index:170}
.sidenav{position:fixed;top:var(--hdr);left:0;bottom:0;z-index:160;box-sizing:border-box;
  width:min(280px,84vw);padding:12px 12px 24px;overflow-y:auto;overscroll-behavior:contain;
  box-shadow:0 0 40px rgb(0 0 0/.45);transform:translateX(-105%);visibility:hidden;
  transition:transform .22s ease,visibility 0s linear .22s}
/* A desktop "collapsed" preference stored on this browser must not hide the
   drawer: same specificity as app.css's display:none, later, so it wins. */
html.nav-collapsed .sidenav{display:block}
html.nav-open .sidenav{transform:none;visibility:visible;transition:transform .22s ease}
.navsticky{position:static;max-height:none;overflow:visible;gap:4px}
.sidenav .dest{padding:12px 14px;font-size:16px}
/* The backdrop is a pseudo-element of .shell: no second <aside>, no template
   change. A tap on it targets DIV.shell, never the Fire/Price under it -- and
   the capture listener consumes that click. cursor:pointer because iOS only
   delivers a click on a non-interactive element that looks clickable. */
html.nav-open .shell{cursor:pointer}
html.nav-open .shell::before{content:"";position:fixed;inset:0;z-index:150;background:rgb(0 0 0/.45)}
@media (prefers-reduced-motion:reduce){.sidenav,html.nav-open .sidenav{transition:none}}

/* The run-in-flight halo lives on the rail logo, which a closed drawer hides;
   ring the toggle instead (SH-11). */
body:has(.runstatus.busy) header.app .navtoggle{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)}

/* ---- Quote Mail toasts (SH-10) -------------------------------------------- */

/* Top-right they covered the actions just under the header. */
.qmtoasts{top:auto;bottom:12px;left:12px;right:12px;width:auto}
