/* mauritz-ui — responsive layer. Layout rules and phone behaviour only; the look
   comes from tokens.css. No build step: link it and it works.
   Breakpoint: 52rem (832px). CSS cannot put a variable in a media query, so this
   number is fixed here. Everything below it is "phone". (kit.js doesn't need it: it
   closes a menu when its opener button stops being visible.)
   Each rule records the bug it prevents — see README.md "The rules". */

/* ═════ 1. Foundations ═════ */
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
/* clip, not hidden: a stray wide element can't widen the page, and position:sticky still works */
html{-webkit-text-size-adjust:100%;overflow-x:clip}
body{margin:0;background-color:var(--ui-bg);color:var(--ui-ink);font-family:var(--ui-font)}
/* No page-wide overflow-wrap: it also splits short letter-spaced labels in narrow
   cells. Long strings (emails, URLs) opt in with .ui-break. */
img,video,svg,canvas,iframe{max-width:100%}
img,video{height:auto}
:focus-visible{outline:3px solid var(--ui-accent);outline-offset:2px}
.ui-visually-hidden{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ═════ 2. Layout primitives — children may always shrink ═════
   Grid and flex items default to min-width:auto, so one long word, email or
   <select> refuses to shrink and widens the page. That caused most overflows. */
.ui-wrap{max-width:var(--ui-maxw);margin-inline:auto;padding-inline:var(--ui-gutter)}
.ui-grid{display:grid;gap:1rem;grid-template-columns:repeat(auto-fill,minmax(min(var(--ui-col-min),100%),1fr))}
.ui-split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.5rem,4vw,3.5rem);align-items:start}
.ui-row{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center}
.ui-grid > *,.ui-split > *,.ui-row > *,.ui-shrink > *{min-width:0}
/* a label column + value column, e.g. contact lists: the value column may shrink */
.ui-pairs > *{display:grid;grid-template-columns:minmax(6rem,auto) minmax(0,1fr);gap:.75rem}
.ui-break{overflow-wrap:anywhere}              /* emails, URLs, IBANs */
/* deliberate sideways scroll (a wide grid that must stay a grid): the box scrolls, not the page */
.ui-scroll-x{overflow-x:auto;overscroll-behavior-x:contain;-webkit-overflow-scrolling:touch;max-width:100%}

/* ═════ 3. Sticky things sit under the top chrome ═════
   --ui-chrome-h is the height of whatever is stuck to the top (0 on desktop by
   default; the phone bar on phones). Never hard-code a sticky offset. */
:root{--ui-chrome-h:0px}
.ui-sticky{position:sticky;top:var(--ui-chrome-h);z-index:20}

/* ═════ 4. App shell: sidebar on desktop, drawer on phones ═════
   <div class="ui-app"> <header class="ui-bar">…</header> <nav class="ui-drawer" id="nav">…</nav>
   <div class="ui-scrim" data-ui-close hidden></div> <main class="ui-main">…</main> </div> */
.ui-app{display:flex;min-height:100vh;min-height:100dvh}
.ui-drawer{flex:0 0 var(--ui-drawer-w);width:var(--ui-drawer-w);position:sticky;top:0;height:100vh;height:100dvh;
  overflow-y:auto;overscroll-behavior:contain;background:var(--ui-bar-bg);color:var(--ui-bar-ink);padding:1rem .75rem;
  display:flex;flex-direction:column;gap:2px}
.ui-main{flex:1 1 auto;min-width:0}
.ui-bar,.ui-scrim,.ui-only-phone{display:none}
.ui-close{display:none}

/* ═════ 5. Site nav: links on desktop, full-screen sheet on phones ═════
   <header class="ui-nav"> … <div class="ui-nav-links">…</div> <button class="ui-burger" data-ui-open="sheet">
   <div class="ui-sheet" id="sheet" hidden>…links…</div> </header> */
.ui-nav{position:sticky;top:0;z-index:60;padding-top:env(safe-area-inset-top)}
.ui-burger{display:none}
.ui-sheet{display:none}
/* The open sheet works at any width, so a project whose links need the burger earlier
   (e.g. at 960px) just shows .ui-burger / hides .ui-nav-links in its own media query;
   kit.js closes the sheet once the burger is hidden again.
   The header itself grows to full screen, not a position:fixed sheet inside it: a
   backdrop-filter/transform/filter on the header makes "fixed" children fixed to the
   header box, so the sheet would be clipped to the bar. */
.ui-nav:has(> .ui-sheet.is-open){position:fixed;inset:0;z-index:60;overflow-y:auto;overscroll-behavior:contain;
  background:var(--ui-bg)}
.ui-sheet.is-open{display:flex;flex-direction:column;
  padding:.5rem var(--ui-gutter) max(1.5rem,env(safe-area-inset-bottom))}
.ui-sheet a{min-height:var(--ui-tap);display:flex;align-items:center;border-bottom:1px solid var(--ui-border)}

/* ═════ 6. Popovers stay on screen ═════
   <span class="ui-pop-host"><button>…</button><div class="ui-pop">…</div></span>
   Centred by default; kit.js flips it to .ui-pop-start/.ui-pop-end when it would hang
   off an edge. A hidden popover is display:none — an invisible one still widens the page. */
.ui-pop-host{position:relative;display:inline-block}
.ui-pop{position:absolute;z-index:30;bottom:calc(100% + 8px);left:50%;transform:translateX(-50%);
  width:max-content;max-width:min(18rem,calc(100vw - 2 * var(--ui-gutter-phone)));
  background:var(--ui-surface);color:var(--ui-ink);border:1px solid var(--ui-border);border-radius:var(--ui-radius-sm);
  box-shadow:var(--ui-shadow);padding:.6rem .75rem;display:none}
.ui-pop.ui-pop-below{bottom:auto;top:calc(100% + 8px)}
.ui-pop.ui-pop-start{left:0;transform:none}
.ui-pop.ui-pop-end{left:auto;right:0;transform:none}
.ui-pop-host:is(:hover,:focus-within) > .ui-pop,.ui-pop-host.is-open > .ui-pop{display:block}

/* ═════ 7. Touch screens have no hover ═════
   Anything revealed on hover (row actions, a "+" in a calendar cell) stays visible. */
.ui-hover-reveal{opacity:0;transition:opacity .15s}
:hover > .ui-hover-reveal,:focus-within > .ui-hover-reveal{opacity:1}
@media (hover:none){.ui-hover-reveal{opacity:1}}

/* ═════ 8. Wide tables become cards on phones: table.ui-stack ═════
   Desktop: a normal table. Phone: each row is a card of "LABEL  value" lines; kit.js
   copies the column headers into data-label. The first cell is the card's title,
   unless a cell has .ui-cell-title. data-label="" shows a cell without a label.
   Only for wide tables — a 2–4 column table reads fine as a table. */
table.ui-stack{width:100%;border-collapse:collapse}

/* ═════════════ PHONE (< 52rem) ═════════════ */
@media (max-width:52rem){
  :root{--ui-gutter:var(--ui-gutter-phone)}
  .ui-only-wide{display:none!important}
  .ui-only-phone{display:revert}

  /* iOS zooms the whole page into any field under 16px and doesn't zoom back.
     This file loads before the project's CSS, so the selector is deliberately heavy
     (:is() gives selects and textareas the input selector's 0,6,1 weight): it beats a
     project's `select{…}` or `.field input{…}`, while an explicit inline style (e.g. a
     big 19px price box) still wins. Not !important: that would also shrink bigger fields. */
  :is(input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=submit]):not([type=button]):not([type=reset]),
  select,textarea){font-size:16px}
  select{max-width:100%}

  /* fixed backgrounds repaint on every scroll frame, and iOS ignores them anyway.
     !important for the same reason: a project's `body{background:… fixed}` loads later. */
  body{background-attachment:scroll!important}

  .ui-split{grid-template-columns:1fr}

  /* 4 — app shell: compact bar + off-canvas drawer */
  :root:has(.ui-bar){--ui-chrome-h:var(--ui-bar-h)}
  .ui-app{flex-direction:column}
  .ui-bar{display:flex;position:sticky;top:0;z-index:60;align-items:center;gap:.6rem;min-height:var(--ui-bar-h);
    padding:.4rem .7rem;padding-top:max(.4rem,env(safe-area-inset-top));
    background:var(--ui-bar-bg);color:var(--ui-bar-ink)}
  .ui-bar-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:650}
  .ui-drawer{position:fixed;inset:0 auto 0 0;z-index:70;height:100vh;height:100dvh;
    padding-top:max(1rem,env(safe-area-inset-top));padding-bottom:max(1rem,env(safe-area-inset-bottom));
    transform:translateX(-102%);visibility:hidden;
    transition:transform .26s var(--ui-ease),visibility 0s linear .26s}
  .ui-drawer.is-open{transform:none;visibility:visible;transition:transform .26s var(--ui-ease);box-shadow:24px 0 60px -20px rgba(0,0,0,.6)}
  .ui-scrim{display:block;position:fixed;inset:0;z-index:65;background:var(--ui-scrim)}
  .ui-scrim[hidden]{display:none}
  .ui-close{display:inline-grid;position:absolute;top:max(.7rem,env(safe-area-inset-top));right:.6rem}
  .ui-drawer a{min-height:var(--ui-tap);display:flex;align-items:center}

  /* 5 — site nav: links give way to the burger (a project may switch earlier, see §5) */
  .ui-nav-links{display:none}
  .ui-burger{display:inline-grid}

  /* 8 — stacked tables */
  table.ui-stack thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
  table.ui-stack,table.ui-stack tbody,table.ui-stack tr,table.ui-stack td{display:block;width:auto}
  table.ui-stack tbody tr{display:flex;flex-direction:column;padding:.65rem .85rem;border-bottom:1px solid var(--ui-border)}
  table.ui-stack tbody tr:last-child{border-bottom:0}
  /* block + floated label, not flex: mixed text and inline elements keep flowing as one line */
  table.ui-stack tbody td{display:block;padding:.2rem 0;border:0;text-align:right;min-width:0;overflow-wrap:anywhere}
  table.ui-stack tbody td::after{content:"";display:table;clear:both}
  table.ui-stack tbody td::before{content:attr(data-label);float:left;max-width:45%;margin-right:.9rem;text-align:left;
    font-family:var(--ui-mono);font-size:.6rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ui-muted);
    font-weight:600;line-height:1.5;padding-top:.2rem}
  table.ui-stack tbody td:first-child,table.ui-stack tbody td.ui-cell-title{order:-1;text-align:left;font-weight:650;font-size:1.05em;padding-bottom:.3rem}
  table.ui-stack tbody td:first-child::before,table.ui-stack tbody td.ui-cell-title::before{display:none}
  table.ui-stack tbody tr:has(.ui-cell-title) td:first-child:not(.ui-cell-title){order:0;text-align:right;font-weight:inherit;font-size:inherit;padding-bottom:.2rem}
  table.ui-stack tbody tr:has(.ui-cell-title) td:first-child:not(.ui-cell-title)::before{display:block}
  table.ui-stack tbody td[data-label=""]::before,table.ui-stack tbody td:not([data-label])::before{display:none}
  table.ui-stack tbody td[colspan]{text-align:left}
  table.ui-stack tbody td:empty{display:none}
  table.ui-stack tbody td > :is(input,select){max-width:60%}
  table.ui-stack tfoot,table.ui-stack tfoot tr,table.ui-stack tfoot td{display:block;text-align:right}
}

/* an open drawer or sheet: the page behind must not scroll */
html.ui-locked,html.ui-locked body{overflow:hidden}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
}
