/* ============================================================================
   White Sand OS — Base / reset / layout primitives / utilities
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  font-family: var(--font);
  font-size: var(--fs-md);
  line-height: var(--lh);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body { overflow: hidden; }

a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: none; }
ul, ol { list-style: none; }
img, svg { display: block; max-width: 100%; }
/* Visible focus ring on keyboard nav only (AA, not color-alone). The 2-stop ring
   reads on any surface. Pointer interactions stay quiet via :focus-visible. */
:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r-xs); }
/* Skip link — first tab stop, jumps to the screen content. */
.skip-link{position:fixed;inset-block-start:8px;inset-inline-start:8px;z-index:999;
  padding:var(--sp-2) var(--sp-4);border-radius:var(--r-sm);background:var(--surface-1);
  border:1px solid var(--line-strong);color:var(--text);font-weight:700;font-size:var(--fs-sm);
  transform:translateY(-200%);transition:transform var(--t-fast)}
.skip-link:focus{transform:translateY(0)}

/* Inline-SVG icon system (js/icons.js). Inherits color + sizes to its slot. */
.icn{display:inline-block;vertical-align:middle;flex-shrink:0;width:1.25em;height:1.25em}
.icn[width]{width:revert;height:revert}

/* numerals/codes always LTR even in RTL layout */
.num, .mono { font-family: var(--mono); font-variant-numeric: tabular-nums; direction: ltr; unicode-bidi: isolate; }

/* ---- Scrollbars (P17 — thin, translucent, track-less) ----------------- */
* { scrollbar-width: thin; scrollbar-color: color-mix(in oklab, var(--text-3) 35%, transparent) transparent; }
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-thumb { background: color-mix(in oklab, var(--text-3) 35%, transparent); border-radius: 3px; }
*::-webkit-scrollbar-thumb:hover { background: color-mix(in oklab, var(--text-3) 55%, transparent); }
*::-webkit-scrollbar-track { background: transparent; }
/* Horizontal tab rows hide their scrollbar entirely (finance centre, etc.). */
.tabs, .tabs-row { scrollbar-width: none; }
.tabs::-webkit-scrollbar, .tabs-row::-webkit-scrollbar { display: none; }

/* ---- Numeric type (spec §1: Archivo for numbers/codes/numeric tables) - */
.num, .t-num, .kpi-val, .kpi-delta, code, kbd, .kbd,
.tbl td.num, .tbl th.num, input.num, input[type="number"], .mono-num {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
}

/* ---- Inline emoji→icon replacements (P15) ----------------------------- */
.emoji-ic{display:inline-flex;align-items:center;justify-content:center;vertical-align:-.14em;line-height:0}
.emoji-ic .icn{width:1em;height:1em}
.emoji-dot{display:inline-block;width:.6em;height:.6em;border-radius:50%;vertical-align:.02em;background:var(--text-3)}
.emoji-dot.is-danger{background:var(--danger)}
.emoji-dot.is-good{background:var(--ok)}
.emoji-dot.is-warn{background:var(--warn)}
.emoji-dot.is-info{background:var(--info)}
.emoji-dot.is-ai{background:var(--ai)}
.emoji-dot.is-muted{background:var(--text-3)}
.emoji-dot.is-ink{background:var(--text)}

/* ---- Headings / text utilities --------------------------------------- */
h1,h2,h3,h4 { font-weight: 700; line-height: 1.25; }
.t-xs{font-size:var(--fs-xs)} .t-sm{font-size:var(--fs-sm)} .t-lg{font-size:var(--fs-lg)}
.t-xl{font-size:var(--fs-xl)} .t-2xl{font-size:var(--fs-2xl)} .t-3xl{font-size:var(--fs-3xl)}
.muted{color:var(--text-2)} .muted-2{color:var(--text-3)}
.b{font-weight:600} .bb{font-weight:700}
.up{text-transform:uppercase; letter-spacing:.06em}
.tabnum{font-variant-numeric:tabular-nums}
.ellip{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.center{text-align:center}
.cap{text-transform:capitalize}

/* ---- Fl/Grid helpers -------------------------------------------------- */
.row{display:flex;align-items:center;gap:var(--sp-3)}
.row.wrap{flex-wrap:wrap}
.col{display:flex;flex-direction:column;gap:var(--sp-3)}
.between{justify-content:space-between}
.gap-1{gap:var(--sp-1)} .gap-2{gap:var(--sp-2)} .gap-4{gap:var(--sp-4)} .gap-6{gap:var(--sp-6)}
.grow{flex:1 1 auto;min-width:0}
.wfull{width:100%}
.hidden{display:none !important}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.spin{animation:spin 1s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes fade-up{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes fade-in{from{opacity:0}to{opacity:1}}
@keyframes pop{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}

/* ---- App frame -------------------------------------------------------- */
#app, #root-screen { height: 100vh; }

.app-frame {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: var(--topbar-h) 1fr;
  grid-template-areas: "side top" "side main";
  height: 100vh;
  transition: grid-template-columns var(--t) var(--ease);
}
.app-frame.collapsed { grid-template-columns: var(--sidebar-w-collapsed) 1fr; }

.app-topbar { grid-area: top; }
.app-side { grid-area: side; }
.app-main {
  grid-area: main;
  overflow: auto;
  /* Enterprise Calm: a quiet canvas. A single, very faint brand wash at the top
     keeps identity without the "glow dashboard" feel; large areas stay neutral. */
  background:
    radial-gradient(1200px 380px at 88% -12%, color-mix(in srgb, var(--brand) 5%, transparent), transparent 70%),
    var(--surface-0);
}
.app-content {
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--sp-6) var(--sp-6) var(--sp-10);
  animation: fade-up var(--t-slow) var(--ease-out);
}
/* Full-bleed opt-out for tables / maps / command centers that need the width. */
.app-content.full, .app-content:has(> .screen-full) { max-width: none; }
.app-content.narrow { max-width: var(--content-narrow); }
@media (prefers-reduced-motion: reduce) { .app-content { animation: none; } }

@media (max-width: 920px) {
  /* The off-canvas sidebar is position:fixed and parked off the inline edge with
     translateX (110% in RTL → past the RIGHT edge). A fixed element escapes any
     ancestor's overflow clip, so it extends the viewport's scrollWidth and reads
     as horizontal body overflow. Clip at the root (the only box that clips a
     fixed descendant). The real scroll container is .app-main, so this never
     affects vertical scroll or sticky descendants. */
  html, body { overflow-x: hidden; }
  .app-frame, .app-frame.collapsed { grid-template-columns: 1fr; grid-template-areas: "top" "main"; }
  .app-side { position: fixed; inset-block: 0; inset-inline-start: 0; z-index: 60; width: var(--sidebar-w);
    transform: translateX(var(--side-off, -110%)); transition: transform var(--t) var(--ease); }
  [dir="rtl"] .app-side { transform: translateX(var(--side-off-rtl, 110%)); }
  .app-frame.mobile-open .app-side { transform: translateX(0) !important; }
  .scrim{position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:55;backdrop-filter:blur(2px)}
  .app-content{padding:var(--sp-4)}
}

/* ---- Page header ------------------------------------------------------ */
.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--sp-4);margin-bottom:var(--sp-6);flex-wrap:wrap}
.page-title{font-size:var(--fs-2xl);font-weight:700;letter-spacing:-.01em;display:flex;align-items:center;gap:var(--sp-3);margin:0}
.page-sub{color:var(--text-2);font-size:var(--fs-sm);margin-top:4px;max-width:62ch}
.page-actions{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap}
@media(max-width:640px){
  .page-head{align-items:stretch}
  .page-actions{width:100%}
  .page-actions .btn{flex:1;min-height:var(--tap)}
}
