/* ============================================================================
   XYZ BIM — brand tokens + base
   v1 · single source of truth for colour, type and motion across every site.

   Load this FIRST, then the shared chrome, then the site's own stylesheet:

     <link rel="preconnect" href="https://brand.xyzbim.eu" crossorigin>
     <link rel="stylesheet" href="https://brand.xyzbim.eu/v1/brand.css">
     <link rel="stylesheet" href="https://brand.xyzbim.eu/v1/site.css">
     <link rel="stylesheet" href="https://brand.xyzbim.eu/v1/app.css">
     <link rel="stylesheet" href="/your-project.css">

   Use a <link>, not @import: an @import is only discovered after the
   importing file has been fetched and parsed, so the tokens arrive a round
   trip late and block first paint behind them.

   The layers:
     brand.css   tokens, faces, base reset          — load it anywhere
     site.css    the shared header and footer       — markup in site.html
     app.css     the components between the header and the content:
                 page head, figures strip, chips, field, empty state
     page.css    interior pages: press kit, map, 404
     chrome.css  the xyzbim.eu HOME PAGE's own components — NOT portable;
                 it needs that page's markup and its JavaScript

   Sites vary by RE-BINDING tokens, never by overriding rules. If you find
   yourself writing !important against this file, add a token instead.

   Light is the default; add data-theme="dark" to <body> (or <html>) for dark.
   ========================================================================= */

/* ---------------------------------------------------------------- type --- */
/* Self-hosted, latin subset. No requests to Google from any site that loads
   this file — keep it that way when adding a face. */
@font-face{ font-family:"Inter"; font-style:normal; font-weight:300; font-display:swap;
  src:url("fonts/inter-latin-300-normal.woff2") format("woff2"); }
@font-face{ font-family:"Inter"; font-style:normal; font-weight:400; font-display:swap;
  src:url("fonts/inter-latin-400-normal.woff2") format("woff2"); }
@font-face{ font-family:"Inter"; font-style:normal; font-weight:500; font-display:swap;
  src:url("fonts/inter-latin-500-normal.woff2") format("woff2"); }
@font-face{ font-family:"Inter"; font-style:normal; font-weight:600; font-display:swap;
  src:url("fonts/inter-latin-600-normal.woff2") format("woff2"); }
/* Public Sans (OFL-1.1, @fontsource/public-sans 5.3.0) - the page and document
   face since 2026-09-11. Before that --f-sans named a system Helvetica that no
   file served, so every Windows visitor read Arial. */
@font-face{ font-family:"Public Sans"; font-style:normal; font-weight:300; font-display:swap;
  src:url("fonts/public-sans-latin-300-normal.woff2") format("woff2"); }
@font-face{ font-family:"Public Sans"; font-style:normal; font-weight:400; font-display:swap;
  src:url("fonts/public-sans-latin-400-normal.woff2") format("woff2"); }
@font-face{ font-family:"Public Sans"; font-style:normal; font-weight:500; font-display:swap;
  src:url("fonts/public-sans-latin-500-normal.woff2") format("woff2"); }
@font-face{ font-family:"Public Sans"; font-style:normal; font-weight:600; font-display:swap;
  src:url("fonts/public-sans-latin-600-normal.woff2") format("woff2"); }
@font-face{ font-family:"JetBrains Mono"; font-style:normal; font-weight:400; font-display:swap;
  src:url("fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2"); }
@font-face{ font-family:"JetBrains Mono"; font-style:normal; font-weight:500; font-display:swap;
  src:url("fonts/jetbrains-mono-latin-500-normal.woff2") format("woff2"); }
@font-face{ font-family:"Fraunces"; font-style:normal; font-weight:400; font-display:swap;
  src:url("fonts/fraunces-latin-400-normal.woff2") format("woff2"); }
@font-face{ font-family:"Fraunces"; font-style:normal; font-weight:500; font-display:swap;
  src:url("fonts/fraunces-latin-500-normal.woff2") format("woff2"); }

:root{
  /* ---- surface & ink ---- */
  /* 2026-09-08: light ground went from cream (#F4F2ED / #EBE7DE, warm
     ink #111) to white with a neutral ink. Decision in the site project doc
     "familia-visual-decisoes". Dark stays as it was: white / ink is the pair. */
  --bg:         #FFFFFF;
  --bg-2:       #F2F3F4;
  --ink:        #0A0A0A;
  --ink-2:      #2C2E31;
  --ink-3:      #6B6F75;
  --rule:       rgba(10,10,10,.14);
  --rule-2:     rgba(10,10,10,.07);
  --accent:     #B94B3A;   /* brick, from the Wolfsburg scan */
  --accent-2:   #0A0A0A;

  /* ---- status ---------------------------------------------------------
     Semantic, not decorative, and deliberately separate from --accent:
     brick means "look here", these mean "this is good" / "this needs
     attention". Sites were carrying their own literals for exactly this
     (competicoes' relevance badges, quemganha's --ok), which is how two
     properties end up with two different greens.
     The -bg pair is the same hue at 16% for a tinted chip. */
  --ok:         #1A7F37;
  --ok-bg:      rgba(26, 127, 55, .16);
  --attn:       #B58900;
  --attn-bg:    rgba(181, 137, 0, .16);

  /* ---- project palette -----------------------------------------------
     One hex per project — the ONLY thing sites differ by. Re-bind in the
     site's own stylesheet (never override rules):

       :root{ --accent: var(--c-quantocustaobra); }
       [data-theme="dark"]{ --accent: var(--c-quantocustaobra-up); }

     `-up` variants lift contrast for dark backgrounds where needed.
     Add a row here when a new project ships; keep names == project slug. */
  --c-quantocustaobra:    #B94B3A;   /* brick — quanto custa a obra */
  --c-quantocustaobra-up: #E6644E;
  --c-pasttenders:        #B94B3A;   /* brick */
  --c-pdm-consult:        #B94B3A;   /* brick */
  --c-monumentosx:        #D4A855;   /* limestone gold */
  --c-monumentosx-dim:    #A07828;
  /* --c-coordenadas (scan blue #2A78D6) removed 2026-08-31: the brand is
     being retired, and the only thing consuming the token was this repo's own
     index.html swatch. tubdemo e finance: unpublished — fora da paleta. */

  /* ---- project palette · homepage hub slugs (xyzbim.eu grid) ------------
     Same contract; these names match the `slug` in xyzbim-astro's
     src/data/projects.json + public/data.js, so the hub cards can paint
     with var(--c-<slug>, <hex fallback>). */
  --c-hbim:        #B94B3A;   /* house brick — the showcase is the house */
  --c-bimconforme: #2E7D5B;   /* bc.css */
  --c-competicoes: #D9A441;
  --c-monumentos:  #5b8a72;   /* monumentos.css */
  --c-casadfl:     #4A7C59;
  --c-attic:       #C9702F;   /* was #C8553D, two steps from the hbim brick; moved to orange 2026-09-08 */
  --c-pointcloud:  #1F3A5F;   /* XYZ BIM Viewer */
  --c-pointcloud-up: #2A5C9E; /* navy does not survive a dark ground; the viewer app binds --accent to this */
  --c-c2c:         #8E5572;
  --c-boq:         #5C8001;
  --c-ids:         #7A306C;
  --c-estimador:   #2F6D6D;
  --c-pdm:         #5B5F97;
  --c-bep99:       #1F4FD8;   /* bep99.css */
  --c-cde:         #0E7490;   /* comparador CDE — cyan escuro */
  --c-cde-up:      #22A0B8;   /* contraste para fundo escuro */
  --c-silveira:    #8E3A22;   /* accent-deep da sala de leitura */
  /* added 2026-09-08 so every hub card paints from a token, not its JSON fallback */
  --c-pesquisa:    #2E6E8E;   /* the research SERIES: coophab, quemganha, anatomia, cde are pieces of it, numbered P·nn, and share this colour */
  --c-precoobra:   #946B2D;
  --c-quemganha:   #4A6F52;   /* kept for the app's own CSS; on the hub it is a Pesquisa piece */
  --c-anatomia:    #3A6EA5;   /* idem */
  --c-coophab:     #B94B3A;   /* idem */
  --c-auditoria:   #5D50C6;   /* was #2F6D6D, identical to estimador; moved to the empty indigo */

  /* ---- type ---- */
  --f-sans:    "Public Sans", Helvetica, Arial, sans-serif;
  --f-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --f-display: var(--f-sans);   /* re-bind per site: monumentos uses a serif */

  --fs-base:   15px;
  --lh-base:   1.5;

  /* ---- rhythm ---- */
  --grid-gap:  24px;
  --pad:       clamp(20px, 3vw, 56px);
  --max:       1680px;
  --radius:    0px;         /* the house style is square */
  --radius-pill: 999px;

  /* ---- motion ---- */
  --tr:        .55s cubic-bezier(.2,.7,0,1);
  --tr-fast:   .22s ease;
  --ease:      cubic-bezier(.2,.7,0,1);
}

/* ---------------------------------------------------------------- dark ---
   The dark palette is declared ONCE, as --d-* aliases, and then mapped onto
   the live tokens in the two places that can turn dark on. Two mappings, one
   set of values: change a colour here and both routes follow. Writing the
   hex twice is how this estate has been bitten before.

   THE THEME CONTRACT (2026-09-10). Three states, and the reader wins by
   default:

     no data-theme        the reader's OS decides, through the media query
     data-theme="dark"    an explicit choice, beats a light OS
     data-theme="light"   an explicit choice, beats a dark OS

   So JavaScript sets the attribute ONLY when the visitor has actually chosen
   one, and leaves it off otherwise. Do not set it to a computed default:
   that is what pinned xyzbim.eu to light for every dark-mode visitor while
   competicoes followed them, and made the two properties look like different
   companies. Put it on <html>, never on <body> - a script reading
   getComputedStyle(document.documentElement) sees only <html>.

   Snippet, in the <head>, before the stylesheet, to avoid a flash:
     <script>try{var t=localStorage.getItem('theme');
       if(t)document.documentElement.setAttribute('data-theme',t);}catch(e){}</script>
   ------------------------------------------------------------------------ */
:root{
  --d-bg:       #0A0A0A;
  --d-bg-2:     #141414;
  --d-ink:      #E8E4DB;
  --d-ink-2:    #C8C2B6;
  --d-ink-3:    #8d897f;
  --d-rule:     rgba(232,228,219,.18);
  --d-rule-2:   rgba(232,228,219,.08);
  --d-accent:   #E6644E;
  --d-accent-2: #E8E4DB;
  --d-ok:       #57AB5A;
  --d-ok-bg:    rgba(87, 171, 90, .18);
  --d-attn:     #D9A441;
  --d-attn-bg:  rgba(217, 164, 65, .18);
}

[data-theme="dark"]{
  --bg:       var(--d-bg);
  --bg-2:     var(--d-bg-2);
  --ink:      var(--d-ink);
  --ink-2:    var(--d-ink-2);
  --ink-3:    var(--d-ink-3);
  --rule:     var(--d-rule);
  --rule-2:   var(--d-rule-2);
  --accent:   var(--d-accent);
  --accent-2: var(--d-accent-2);
  --ok:       var(--d-ok);
  --ok-bg:    var(--d-ok-bg);
  --attn:     var(--d-attn);
  --attn-bg:  var(--d-attn-bg);
}

@media (prefers-color-scheme: dark){
  /* The :not() is what lets an explicit light choice beat a dark OS. */
  :root:not([data-theme="light"]){
    --bg:       var(--d-bg);
    --bg-2:     var(--d-bg-2);
    --ink:      var(--d-ink);
    --ink-2:    var(--d-ink-2);
    --ink-3:    var(--d-ink-3);
    --rule:     var(--d-rule);
    --rule-2:   var(--d-rule-2);
    --accent:   var(--d-accent);
    --accent-2: var(--d-accent-2);
    --ok:       var(--d-ok);
    --ok-bg:    var(--d-ok-bg);
    --attn:     var(--d-attn);
    --attn-bg:  var(--d-attn-bg);
  }
}

/* Type variants, switched with data-font on <body>.
   The rule (MARCA.md, 2026-09-09; face changed 2026-09-11): pages and documents
   read in the default Public Sans stack; application interfaces set data-font="inter" (self-hosted,
   identical on every OS, drawn for small sizes); labels and codes are
   --f-mono in both. */
[data-font="inter"]    { --f-sans: "Inter", Helvetica, system-ui, sans-serif; --f-display: var(--f-sans); }
[data-font="fraunces"] { --f-display: "Fraunces", Georgia, serif; --f-sans: "Inter", Helvetica, sans-serif; }

/* ---------------------------------------------------------------- base --- */
*, *::before, *::after{ box-sizing: border-box; }
html, body{ margin: 0; padding: 0; }
html{ scroll-behavior: smooth; }

body{
  background: var(--bg);
  color: var(--ink);
  font-family: var(--f-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background var(--tr), color var(--tr);
}

a{ color: inherit; text-decoration: none; }
button{ font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
img{ max-width: 100%; display: block; }
em{ font-style: italic; }

h1, h2, h3, h4{ font-family: var(--f-display); font-weight: 400; margin: 0; }

/* The mono voice — labels, codes, metadata. Used on every site. */
.mono{
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink-2);
}

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