/* BarazaBrief base — reset, typography, container/grid, focus, motion.
   Needs tokens.css. Components come in T-007. See DESIGN.md §3, §5, §7. */

*, *::before, *::after { box-sizing: border-box; border-radius: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font: 400 1rem/1.5 var(--font-body);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, video, svg { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
a { color: inherit; }
table { border-collapse: collapse; }
hr { border: 0; border-top: 1px solid var(--border); margin: 0; }

h1, h2, h3 { font-family: var(--font-display); text-wrap: balance; }
p { text-wrap: pretty; }
.tabular { font-variant-numeric: tabular-nums; }
.mono-label { font: 500 .75rem/1.3 var(--font-mono); letter-spacing: .08em; text-transform: uppercase; }

::selection { background: var(--accent-tint); color: var(--text); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
a, button, input, select, textarea {
  transition-duration: var(--t-fast); transition-timing-function: var(--ease);
}

.skip-link { position: absolute; left: var(--s-4); top: -100px; z-index: 100;
  padding: var(--s-3) var(--s-4); background: var(--text); color: var(--text-inverse); }
.skip-link:focus { top: var(--s-4); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; }

.bb-container { width: 100%; max-width: calc(var(--container) + 2 * var(--gutter-x));
  margin-inline: auto; padding-inline: var(--gutter-x); }
.bb-grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gap); row-gap: 2rem; }
.bb-span-3 { grid-column: span 3; } .bb-span-4 { grid-column: span 4; }
.bb-span-6 { grid-column: span 6; } .bb-span-8 { grid-column: span 8; }
.bb-span-9 { grid-column: span 9; } .bb-span-12 { grid-column: 1 / -1; }
.bb-grid--quad > * { grid-column: span 3; }
.bb-grid--trio > * { grid-column: span 4; }
@media (max-width: 1023px) {
  .bb-span-3, .bb-span-4, .bb-span-8, .bb-span-9 { grid-column: 1 / -1; }
  .bb-grid--quad > * { grid-column: span 6; }
  .bb-grid--trio > * { grid-column: span 4; }
}
@media (max-width: 767px) { .bb-span-6, .bb-grid--quad > *, .bb-grid--trio > * { grid-column: 1 / -1; } }

@keyframes bb-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.bb-in > * { animation: bb-rise 240ms ease-out both; animation-delay: calc(var(--i, 0) * 40ms); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important;
    transition-duration: 1ms !important; scroll-behavior: auto !important; }
  .bb-in > * { animation: none; }
}

/* chrome wrappers are layout-transparent so the masthead can be sticky against <body> */
#chrome-top, #chrome-bottom { display: contents; }

/* Reserve the header's height until site.js draws it. #chrome-top is empty in
   the served HTML and chrome() fills it only after the JSON data loads, while
   <main>'s static skeleton paints at once - without this the header arrives
   above content already on screen and pushes it down (CLS ~1.0 measured on
   home). Heights = masthead + nav + ticker, measured on the live header:
   163 from 768px up, 207 at 360-767, 263 below 360 (header wraps to a third row).
   :empty stops matching the moment chrome() writes into the div. If the header
   changes height, re-measure `main`'s top offset and update these three. */
#chrome-top:empty { display: block; min-height: 163px; }
@media (max-width: 767px) { #chrome-top:empty { min-height: 207px; } }
@media (max-width: 359px) { #chrome-top:empty { min-height: 263px; } }

/* ...and keep <main> unpainted until the same moment: every page calls
   chrome() and fills its content in the same task, so while #chrome-top is
   empty the content is not ready either, and an invisible element's movement
   is not a layout shift. Safety net: if JS or the data fails, visibility
   returns after 3s so no page stays blank. */
#chrome-top:empty ~ main { visibility: hidden; animation: bb-reveal 0s linear 3s forwards; }
@keyframes bb-reveal { to { visibility: visible; } }
