/* maclotsen.nl -- colour tokens.
 *
 * TWO LAYERS, ONE RULE.
 *
 *   Layer 1  a terminal palette: sixteen authored colours plus a neutral ramp.
 *            Authored, never derived -- an ANSI palette is a set of decisions,
 *            not a hue rotation.
 *   Layer 2  semantic tokens. Component CSS may use ONLY these. Swapping the
 *            whole look then means editing layer 1 and nothing else.
 *
 * THE COLOUR MAPPING IS THE HONESTY MAPPING.
 *
 *   green    axis 1, publicly verifiable. Links are green because they are
 *            checkable -- you can click one and see the repository.
 *   cyan     axis 2, paid engagements. Attested by the CV, not clickable.
 *   magenta  the commercial seam. Used only on /cv/, so money is quarantined
 *            to one page and never colours the evidence.
 *   yellow   caveats: archived, borderline fork, self-reported count.
 *   red      errors only.
 *
 * A skill that is strong on one axis and empty on the other therefore looks
 * different at a glance from one that is strong on both, without the reader
 * having to parse two numbers. The design carries the claim.
 *
 * Deliberately distant from the Xerdi house colours (#174A67 / #17675c):
 * doc/sales/positionering.tex requires maclotsen.nl to stand apart visually
 * while cross-linking to the company.
 *
 * CONTRAST IS CHECKED, NOT ASSUMED. `make contrast` resolves every pair in
 * data/contrast-pairs.yaml against this file, for both themes, and fails the
 * build on a shortfall. The dim neutral is where terminal palettes normally
 * fail; here it is 7.8:1 (dark) and 5.7:1 (light).
 *
 * The `@theme` comments are load-bearing: contrast.py parses them. The dark
 * palette is written twice -- once for the explicit toggle, once for the OS
 * preference -- and tests/test_contrast.py asserts the two blocks are
 * identical, so the duplication is a checked invariant rather than a hazard.
 */

/* @theme light */
:root {
  /* -- layer 1: neutral ramp (paper terminal) ---------------------------- */
  --paper-000: #f4f2ec;   /* page */
  --paper-100: #eae7dd;   /* raised surface */
  --paper-400: #78857f;   /* rules and boundaries      3.4:1 */
  --paper-600: #55625e;   /* secondary text            5.7:1 */
  --paper-800: #1b2422;   /* body text                14.2:1 */
  --paper-900: #0a0f0e;   /* emphasis                 17.3:1 */

  /* -- layer 1: the sixteen ------------------------------------------------ */
  --ansi-black:          #1b2422;
  --ansi-red:            #b02a2e;
  --ansi-green:          #17703d;
  --ansi-yellow:         #7a5a12;
  --ansi-blue:           #1c5a92;
  --ansi-magenta:        #9c3a8c;
  --ansi-cyan:           #0d6f78;
  --ansi-white:          #55625e;
  --ansi-bright-black:   #78857f;
  --ansi-bright-red:     #8f1f23;
  --ansi-bright-green:   #146638;
  --ansi-bright-yellow:  #8a5a00;
  --ansi-bright-blue:    #164a78;
  --ansi-bright-magenta: #7f2c72;
  --ansi-bright-cyan:    #0a5b63;
  --ansi-bright-white:   #0a0f0e;

  /* -- layer 2: semantic --------------------------------------------------- */
  --bg:          var(--paper-000);
  --bg-raise:    var(--paper-100);
  --rule:        var(--paper-400);
  --fg-dim:      var(--paper-600);
  --fg:          var(--paper-800);
  --fg-strong:   var(--paper-900);

  --axis-public: var(--ansi-green);         /* verifiable, linkable */
  --axis-paid:   var(--ansi-cyan);          /* attested, not linkable */
  --paid-seam:   var(--ansi-magenta);       /* the commercial offer, /cv/ only */
  --warn:        var(--ansi-yellow);
  --err:         var(--ansi-red);
  --link:        var(--axis-public);
  --focus:       var(--ansi-bright-yellow);

  /* Engraved music. Full ink here: on a light ground this is what a score has
     always been, and printed sheet music is higher contrast still. The dark
     themes soften it -- see the note there. */
  --score-ink:   var(--fg);
}

/* @theme dark */
:root[data-theme="dark"] {
  --paper-000: #0b0f0d;
  --paper-100: #131917;
  --paper-400: #5c7069;
  --paper-600: #9aa8a3;
  --paper-800: #d7e0dc;
  --paper-900: #f2f7f5;

  --ansi-black:          #0b0f0d;
  --ansi-red:            #e0666a;
  --ansi-green:          #4bbf74;
  --ansi-yellow:         #d4a94f;
  --ansi-blue:           #6aa9e0;
  --ansi-magenta:        #c96fbd;
  --ansi-cyan:           #3fb8c2;
  --ansi-white:          #d7e0dc;
  --ansi-bright-black:   #5c7069;
  --ansi-bright-red:     #f2777a;
  --ansi-bright-green:   #5fd68a;
  --ansi-bright-yellow:  #e8c46a;
  --ansi-bright-blue:    #8cc2f0;
  --ansi-bright-magenta: #e08bd4;
  --ansi-bright-cyan:    #4fd0da;
  --ansi-bright-white:   #f2f7f5;

  --axis-public: var(--ansi-bright-green);
  --axis-paid:   var(--ansi-bright-cyan);
  --paid-seam:   var(--ansi-bright-magenta);
  --warn:        var(--ansi-bright-yellow);
  --err:         var(--ansi-bright-red);
  --focus:       var(--ansi-bright-yellow);

  /* Not --fg. A score is a large, dense field of fine lines, and near-white
     ink over that much dark ground glares in a way black-on-paper never does
     -- the complaint is specific to this theme. --fg-dim gives 7.81:1, well
     clear of the 4.5:1 for text and the 3:1 for the staff lines themselves,
     while taking the edge off. Text elsewhere keeps full --fg. */
  --score-ink:   var(--fg-dim);
}

@media (prefers-color-scheme: dark) {
  /* @theme dark-media */
  :root:not([data-theme="light"]) {
    --paper-000: #0b0f0d;
    --paper-100: #131917;
    --paper-400: #5c7069;
    --paper-600: #9aa8a3;
    --paper-800: #d7e0dc;
    --paper-900: #f2f7f5;

    --ansi-black:          #0b0f0d;
    --ansi-red:            #e0666a;
    --ansi-green:          #4bbf74;
    --ansi-yellow:         #d4a94f;
    --ansi-blue:           #6aa9e0;
    --ansi-magenta:        #c96fbd;
    --ansi-cyan:           #3fb8c2;
    --ansi-white:          #d7e0dc;
    --ansi-bright-black:   #5c7069;
    --ansi-bright-red:     #f2777a;
    --ansi-bright-green:   #5fd68a;
    --ansi-bright-yellow:  #e8c46a;
    --ansi-bright-blue:    #8cc2f0;
    --ansi-bright-magenta: #e08bd4;
    --ansi-bright-cyan:    #4fd0da;
    --ansi-bright-white:   #f2f7f5;

    --axis-public: var(--ansi-bright-green);
    --axis-paid:   var(--ansi-bright-cyan);
    --paid-seam:   var(--ansi-bright-magenta);
    --warn:        var(--ansi-bright-yellow);
    --err:         var(--ansi-bright-red);
    --focus:       var(--ansi-bright-yellow);

    /* Same reason as the explicit dark theme above. */
    --score-ink:   var(--fg-dim);
  }
}
