/* ============================================================================
   Kodexa presentation theme
   ----------------------------------------------------------------------------
   One canonical set of tokens for every deck in this repo. Values are taken
   from www.kodexa.ai's own custom properties, so a deck and the site agree.
   The site's variable name is noted beside each one.

   Link it before the deck's own <style> block:
       <link rel="stylesheet" href="../assets/theme.css">

   Decks come in two grounds and both are correct. Narrative decks run light.
   Technical decks run dark, because their diagrams encode meaning in colour and
   luminous accents need a dark ground to stay legible. Put class="dark" on
   <html> to select the dark ground; light is the default.

   Do not redefine these values inside a deck. If a deck needs a colour that is
   not here, add it here.
   ============================================================================ */

/* ---- typefaces -------------------------------------------------------------
   Self-hosted so a deck renders correctly behind a corporate network that
   blocks Google Fonts. Both files are variable, so one covers every weight. */

@font-face {
  font-family: "Archivo";
  src: url("fonts/archivo-var.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Geist Mono";
  src: url("fonts/geistmono-var.woff2") format("woff2-variations");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --sans: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, Monaco, monospace;

  /* Archivo is the display face. The site sets headings at 700 with tight
     tracking; these two keep every deck's headings on the same footing. */
  --display-weight: 700;
  --display-tracking: -0.03em;

  /* ---- brand ------------------------------------------------------------- */
  --blue:       #1258a8;   /* --kodexa-blue      */
  --blue-soft:  #3b7fd0;   /* --kodexa-blue-soft */
  --blue-lift:  #5b9fe6;   /* --primary, the readable blue on dark ground */
  --cyan:       #00aeef;   /* --kodexa-cyan      */

  /* ---- light ground, the default ----------------------------------------- */
  --bg:         #faf8f4;   /* --paper     */
  --surface:    #ffffff;   /* --surface   */
  --ink:        #0a0c10;   /* --kodexa-ink       */
  --ink-soft:   #5b616b;   /* --kodexa-gray      */
  --ink-faint:  #9aa1ac;   /* --muted-foreground */
  --rule:       #e9e5dd;   /* --hairline  */
  --accent:     var(--blue);
  --accent-wash:#e8f0fa;

  /* the site's own names, so markup lifted from kodexa.ai resolves as written */
  --kodexa-blue: var(--blue);
  --kodexa-cyan: var(--cyan);
  --kodexa-ink:  #0a0c10;
  --kodexa-gray: #5b616b;
  --paper:       #faf8f4;

  /* ---- recurring concepts ------------------------------------------------
     These carry meaning across decks, so a reader learns them once. Use the
     token, not the hex, and use the same token for the same idea everywhere.

     The hues are not new. The decks in this repo had already converged on warm
     tan for people, violet for the model, teal for knowledge and grey for a
     caller's own systems. This only writes that down and fixes the light-ground
     equivalents, which had never existed. */
  --c-model:   var(--blue);   /* a model reads            */
  --c-rule:    #0d7fa8;       /* a rule or script runs. A darkened cyan: the brand
                                 #00aeef is only 2.4:1 on paper and fails as a mark */
  --c-person:  #a8712c;       /* a person decides         */
  --c-system:  #5b616b;       /* your own system is called */
  --c-agent:   #7c5cd3;       /* an agent works it        */
  --c-know:    #0f8a7e;       /* knowledge, what is kept  */
  --c-warn:    #9c6b16;       /* needs attention          */
}

/* ---- dark ground -----------------------------------------------------------
   Same names, restated for dark. A deck written against the tokens above needs
   no other change; it inherits correct values here. Accents lift to the
   readable blue rather than the deep one, which fails contrast on dark. */

html.dark {
  --bg:         #0a0c10;   /* --background        */
  --surface:    #121620;   /* --card              */
  --ink:        #f2f0ea;   /* --foreground        */
  --ink-soft:   #9aa1ac;   /* --muted-foreground  */
  --ink-faint:  #6b7280;   /* --chart-5           */
  --rule:       #262a33;   /* --border            */
  --accent:     var(--blue-lift);
  --accent-wash:#18202b;   /* --accent            */

  --c-model:   var(--blue-lift);
  --c-rule:    var(--cyan);
  --c-person:  #d5a463;
  --c-system:  #9aa1ac;
  --c-agent:   #b98ae8;
  --c-know:    #3fc9b0;
  --c-warn:    #e0a94a;
}

/* ---- base ------------------------------------------------------------------
   Deliberately small. Decks own their own layout; this only fixes the things
   that were drifting: the typeface, the ground, and heading treatment.

   Everything below is wrapped in :where(), which carries zero specificity. So
   these are defaults a deck inherits, never rules a deck has to fight. That
   matters for we-believe-intro, which is a compiled export with its own
   utility classes: it takes the tokens above and ignores the styling here. */

:where(html), :where(body) {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-weight: 400;
  letter-spacing: -0.003em;
  -webkit-font-smoothing: antialiased;
}

:where(h1, h2, h3) {
  font-family: var(--sans);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  line-height: 1.1;
}

/* Numerals, labels and anything code-ish. Matches the site. */
:where(.mono, code, kbd, samp) { font-family: var(--mono); }

/* ---- shared components -----------------------------------------------------
   The two pieces of furniture every deck carries. Unlike the base above these
   are real rules, not :where() defaults, because a deck is meant to use them
   rather than restate them. If one of these needs to change, change it here.
   ============================================================================ */

/* ---- the brand lockup ------------------------------------------------------
   Same mark, same size, same corner, in every deck — and it is always the way
   back to the index. First thing in <body>:

       <a class="kx-brand" href="../"><img src="../assets/kodexa-logo.png" alt="Kodexa"></a>

   A deck with a header puts it in that header. A full-screen slide deck has no
   header to put it in, so it adds kx-brand--fixed and the mark floats in the
   same corner instead. Set --brand-height to depart from 28px; the index page
   runs larger. */

.kx-brand {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  flex: 0 0 auto;
}
.kx-brand img {
  height: var(--brand-height, 28px);
  width: auto;
  display: block;
}
.kx-brand--fixed {
  position: fixed;
  top: 1.25rem;
  left: 1.5rem;
  z-index: 50;
}
.kx-brand:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 5px;
  border-radius: 2px;
}

/* ---- the eyebrow -----------------------------------------------------------
   The small uppercase line above a title. One treatment in two voices: the
   default speaks in the accent, --muted steps back to a caption. The optional
   LED reads as "this one is live" and takes the eyebrow's own colour unless the
   deck sets --led.

       <div class="kx-eyebrow"><span class="led"></span>In production</div>
       <div class="kx-eyebrow kx-eyebrow--muted">Foundations</div>            */

.kx-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
}
.kx-eyebrow--muted {
  color: var(--ink-soft);
  font-weight: 500;
}
.kx-eyebrow .led {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: var(--led, currentColor);
  animation: kx-led-pulse 2s ease-out infinite;
}
@keyframes kx-led-pulse {
  0%   { box-shadow: 0 0 0 0    color-mix(in oklab, var(--led, currentColor) 60%, transparent); }
  70%  { box-shadow: 0 0 0 12px color-mix(in oklab, var(--led, currentColor) 0%,  transparent); }
  100% { box-shadow: 0 0 0 0    color-mix(in oklab, var(--led, currentColor) 0%,  transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .kx-eyebrow .led { animation: none; }
}
