/* Shared chrome owns header geometry on every page, including the live tools. */
:root{--site-header-height:var(--shell-header-height)}
html{scrollbar-gutter:stable;background:var(--bg)}
#site-header{box-sizing:border-box;flex:none;width:100%;height:var(--site-header-height);min-height:var(--site-header-height);max-width:1600px;margin:0 auto;padding:var(--shell-header-top) var(--shell-inset) 0;display:flex;align-items:center;justify-content:space-between;gap:var(--shell-nav-gap);border-bottom:var(--shell-divider) solid var(--line);background:var(--bg);color:var(--fg);font:var(--shell-nav-size) var(--mono)}
#site-header .wordmark{display:flex;flex:none;align-items:center}
#site-header .wordmark img{filter:var(--logo-filter);display:block;width:128px;height:40px;max-height:40px;object-fit:contain}
#site-header nav{display:flex;align-items:center;gap:var(--shell-nav-gap);font:inherit;min-width:0}
#site-header nav a{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 2px;white-space:nowrap;text-decoration:none;color:var(--muted);font:var(--shell-nav-size) var(--mono);box-shadow:none;transition:color 120ms ease-out}
#site-header nav a:hover,#site-header nav a[aria-current=page]{color:var(--fg)}
#site-header nav a[aria-current=page]{box-shadow:inset 0 -1px var(--fg)}
#site-header nav #account-link{min-width:calc(9ch + 4px)}
#site-header:has(.site-account) nav{margin-left:auto}
#site-header .site-account{display:none;flex:none;align-items:center;min-height:32px;padding:0 9px;border:1px solid var(--muted);border-radius:3px;color:var(--fg);font:12.5px 'IBM Plex Mono',ui-monospace,monospace;white-space:nowrap;text-decoration:none}
#site-header .site-account:hover{background:var(--tile2)}
#site-header a:focus-visible{outline:1px solid var(--fg);outline-offset:3px}
/* No curtain (R15 performance, docs/design/frontend-performance.md): server-rendered content paints at once. A region
   still waiting for data shows its own small placeholder (.pending-late appears only after 300 ms); page.js adds the
   in-place #page-loading note only when a page has still not settled after 18 s. */
#page-loading{margin:16px 24px;text-align:center;color:var(--muted);font:14px var(--sans)}
#page-loading p{margin:0 0 8px}
.pending-late{animation:pending-late 1ms 300ms both}
@keyframes pending-late{from{visibility:hidden}to{visibility:visible}}
body[data-screen] main>section:not([hidden]){animation:page-arrive 160ms ease-out}
@keyframes page-arrive{from{opacity:0}to{opacity:1}}
@keyframes nav-more{from,99%{-webkit-mask-image:linear-gradient(to right,black calc(100% - 24px),transparent);mask-image:linear-gradient(to right,black calc(100% - 24px),transparent)}to{-webkit-mask-image:none;mask-image:none}}
@media(max-width:600px){
  #site-header{display:grid;grid-template-rows:36px 44px;gap:0;justify-content:stretch}
  #site-header .wordmark{grid-area:1/1;justify-self:start}
  #site-header nav{grid-area:2/1}
  #site-header .site-account{grid-area:1/1;justify-self:end;min-height:28px}
  #site-header .wordmark img{width:112px;height:34px}
  #site-header nav{width:100%;justify-content:space-between;gap:4px;font-size:12px}
  #site-header nav a{min-width:44px}
  /* Six items do not fit a phone (ruling 2026-10-17): the nav is one scrolling row, labels at full size, scrollbar hidden,
     a 24 px fade on the right while items are off-screen (scroll timeline, or page.js sets data-more). */
  #site-header nav{position:relative;justify-content:flex-start;gap:var(--shell-nav-gap);flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain}
  #site-header nav::-webkit-scrollbar{display:none}
  #site-header nav a{flex:none}
  #site-header nav[data-more=true]{-webkit-mask-image:linear-gradient(to right,black calc(100% - 24px),transparent);mask-image:linear-gradient(to right,black calc(100% - 24px),transparent)}
  @supports (animation-timeline:scroll()){
    #site-header nav:not([data-more]){animation:nav-more linear both;animation-timeline:scroll(self inline)}
  }
}
/* Outer site footers use the shell inset; nested legal/account footers already align with their content. */
:root :is(.site-footer,.account-footer,.pricing-footer,.legal footer){padding-block:var(--shell-footer-pad);row-gap:var(--shell-footer-row-gap);column-gap:var(--shell-footer-column-gap)}
:root .site-footer{padding-inline:var(--shell-inset)}
:root :is(.account-footer,.pricing-footer,.legal footer){padding-inline:0}
:root :is(.site-footer,.account-footer,.pricing-footer)>div{gap:var(--shell-footer-column-gap)}
@media(prefers-reduced-motion:reduce){
  body[data-screen] main>section:not([hidden]){animation:none}
  #site-header nav a{transition:none}
}
