@layer tokens {

/* ============================================================
   TY MABEE - FIELD JOURNAL · design tokens
   ------------------------------------------------------------
   Three tiers, and the middle one is the point:

     TIER 1  raw pigments        never referenced by a component
     TIER 2  semantic roles      THE EXISTING NAMES, UNCHANGED
     TIER 3  derived values      kills every hard-coded literal

   Because tier 2 keeps the original variable names, switching
   the whole journal to lamplight costs zero component rules -
   only the tier-2 map is remapped.
   ============================================================ */

/* ------------------------------------------------------------
   TIER 1 · raw pigments
   Do not reference these outside this file.
   ------------------------------------------------------------ */
:root {
  /* daylight - earth tones on cream */
  --pig-cream:      #f4eee0;
  --pig-cream-2:    #ece3cf;
  --pig-cream-3:    #e4d8bd;
  --pig-card:       #fbf7ec;   /* polaroid / postcard stock, lighter than paper */
  --pig-ink:        #2b2317;
  --pig-ink-soft:   #5c5243;
  --pig-forest:     #2e4b34;
  --pig-forest-d:   #1f3626;
  --pig-walnut:     #7a5537;
  --pig-rust:       #9c512e;   /* 4.53:1 even on the deeper paper stock */
  --pig-amber:      #c99e46;
  --pig-vermilion:  #9c3b2e;

  /* lamplight - the same journal, read after dusk.
     white gouache and coloured pencil on toned stock. */
  --lamp-paper:     #14120d;
  --lamp-paper-2:   #1c1811;
  --lamp-paper-3:   #241f15;
  --lamp-card:      #1a1610;
  --lamp-ink:       #e8dcc2;
  --lamp-ink-soft:  #a2957a;
  --lamp-forest:    #8fb894;
  --lamp-forest-d:  #b5d2b8;
  --lamp-walnut:    #c0966b;
  --lamp-rust:      #e0855b;
  --lamp-amber:     #e8bf6b;
  --lamp-vermilion: #e07a63;
}

/* ------------------------------------------------------------
   TIER 2 · semantic roles
   These names are load-bearing - every component rule in the
   project refers to them and to nothing else.
   ------------------------------------------------------------ */
:root {
  color-scheme: light;
  --paper:       var(--pig-cream);
  --paper-warm:  var(--pig-cream-2);
  --paper-deep:  var(--pig-cream-3);
  --stock:       var(--pig-card);
  --ink:         var(--pig-ink);
  --ink-soft:    var(--pig-ink-soft);
  --green:       var(--pig-forest);
  --green-deep:  var(--pig-forest-d);
  --brown:       var(--pig-walnut);
  --rust:        var(--pig-rust);
  --amber:       var(--pig-amber);
  --stamp-red:   var(--pig-vermilion);

  --grain-blend:   multiply;
  --grain-opacity: 0.12;
  --stamp-blend:   multiply;

  /* Shadows are cast by paper onto a desk, so they darken the ground
     no matter which way round the page is. This is the one role that
     must NOT follow --ink: under lamplight --ink is cream, and
     shadows derived from it came out as glows. */
  --shade: var(--pig-ink);
}

/* The lamplight remap is written out twice - once for the explicit
   choice, once for the system preference. CSS cannot swap a token
   *group* wholesale without a preprocessor, and the alternatives
   (space-toggle hacks, or making JS always write an explicit
   data-theme) cost either readability or no-JS dark mode.
   If you edit one block, edit the other. */
:root[data-theme="lamp"] {
  color-scheme: dark;
  --paper:       var(--lamp-paper);
  --paper-warm:  var(--lamp-paper-2);
  --paper-deep:  var(--lamp-paper-3);
  --stock:       var(--lamp-card);
  --ink:         var(--lamp-ink);
  --ink-soft:    var(--lamp-ink-soft);
  --green:       var(--lamp-forest);
  --green-deep:  var(--lamp-forest-d);
  --brown:       var(--lamp-walnut);
  --rust:        var(--lamp-rust);
  --amber:       var(--lamp-amber);
  --stamp-red:   var(--lamp-vermilion);

  /* multiply darkens toward black, so on a dark ground it turns the
     grain to mud - soft-light keeps the texture readable. Stamps need
     the opposite of multiply rather than a softening of it: screen is
     what lets light ink sit on dark stock and still look pressed in.
     Under soft-light they were very nearly invisible. */
  --grain-blend:   soft-light;
  --grain-opacity: 0.20;
  --stamp-blend:   screen;

  --shade: #000;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="day"]):not([data-theme="lamp"]) {
    color-scheme: dark;
    --paper:       var(--lamp-paper);
    --paper-warm:  var(--lamp-paper-2);
    --paper-deep:  var(--lamp-paper-3);
    --stock:       var(--lamp-card);
    --ink:         var(--lamp-ink);
    --ink-soft:    var(--lamp-ink-soft);
    --green:       var(--lamp-forest);
    --green-deep:  var(--lamp-forest-d);
    --brown:       var(--lamp-walnut);
    --rust:        var(--lamp-rust);
    --amber:       var(--lamp-amber);
    --stamp-red:   var(--lamp-vermilion);

    --grain-blend:   soft-light;
    --grain-opacity: 0.20;
    --stamp-blend:   screen;

    --shade: #000;
  }
}

/* ------------------------------------------------------------
   TIER 3 · derived
   Every one of these replaced a hard-coded rgba() literal that
   was tuned for cream and would have broken under lamplight.

   Each is declared twice: a plain literal first, then the
   relative-colour version. An unsupported *function* invalidates
   the declaration at parse time, so the literal above it is used.
   That makes the first line a real fallback, not decoration.
   ------------------------------------------------------------ */
:root {
  /* rules & hairlines */
  --rule-hair:   rgba(43, 35, 23, 0.14);
  --rule-hair:   rgb(from var(--ink) r g b / 0.14);
  --rule-edge:   rgba(43, 35, 23, 0.25);
  --rule-edge:   rgb(from var(--ink) r g b / 0.25);
  --rule-strong: rgba(43, 35, 23, 0.35);
  --rule-strong: rgb(from var(--ink) r g b / 0.35);
  --rule-dash:   rgba(92, 82, 67, 0.45);
  --rule-dash:   rgb(from var(--ink-soft) r g b / 0.45);
  --rule-dot:    rgba(92, 82, 67, 0.40);
  --rule-dot:    rgb(from var(--ink-soft) r g b / 0.40);
  --rule-faint:  rgba(43, 35, 23, 0.15);
  --rule-faint:  rgb(from var(--ink) r g b / 0.15);

  /* shadows - always hard offsets or tight drops, never soft glows */
  --shadow-tape:  0 1px 2px rgba(43, 35, 23, 0.10);
  --shadow-tape:  0 1px 2px rgb(from var(--shade) r g b / 0.10);
  --shadow-soft:  0 3px 7px rgba(43, 35, 23, 0.09);
  --shadow-soft:  0 3px 7px rgb(from var(--shade) r g b / 0.09);
  --shadow-photo: 2px 4px 12px rgba(43, 35, 23, 0.18);
  --shadow-photo: 2px 4px 12px rgb(from var(--shade) r g b / 0.18);
  --shadow-lift:  3px 6px 0 rgba(43, 35, 23, 0.15);
  --shadow-lift:  3px 6px 0 rgb(from var(--shade) r g b / 0.15);
  --shadow-hard:  4px 8px 0 rgba(43, 35, 23, 0.12);
  --shadow-hard:  4px 8px 0 rgb(from var(--shade) r g b / 0.12);
  --shadow-drag:  6px 14px 24px rgba(43, 35, 23, 0.28);
  --shadow-drag:  6px 14px 24px rgb(from var(--shade) r g b / 0.28);
  --drop-sticker: 1px 2px 0 rgba(43, 35, 23, 0.20);
  --drop-sticker: 1px 2px 0 rgb(from var(--shade) r g b / 0.20);
  --drop-stamp:   1px 2px 0 rgba(43, 35, 23, 0.15);
  --drop-stamp:   1px 2px 0 rgb(from var(--shade) r g b / 0.15);

  /* fills & washes */
  --graph-line:  rgba(122, 85, 55, 0.07);
  --graph-line:  rgb(from var(--brown) r g b / 0.07);
  --leaf-fill:   rgba(46, 75, 52, 0.14);
  --leaf-fill:   rgb(from var(--green) r g b / 0.14);
  --tape:        rgba(222, 202, 152, 0.60);
  --tape:        rgb(from var(--amber) r g b / 0.34);
  --tape-strip:  rgba(222, 202, 152, 0.50);
  --tape-strip:  rgb(from var(--amber) r g b / 0.28);
  --cover-wash:  rgba(201, 158, 70, 0.06);
  --cover-wash:  rgb(from var(--amber) r g b / 0.06);
  --postmark-ln: rgba(92, 82, 67, 0.50);
  --postmark-ln: rgb(from var(--ink-soft) r g b / 0.50);
  /* The postmark copy is only 8px; keep its ink solid for text contrast. */
  --postmark-fg: #5c5243;
  --postmark-fg: var(--ink-soft);

  /* Brass labels stay brass under lamplight; both pigments are fixed so
     the small mono engraving keeps its daylight contrast after remapping. */
  --cabinet-plaque-bg: var(--pig-amber);
  --cabinet-plaque-fg: var(--pig-forest-d);

  /* The colophon is a dark printed panel in BOTH themes - it is the
     one surface that does not invert. Under lamplight an inverting
     colophon would put amber links on pale green at ~1.1:1. */
  --colophon-bg:   var(--pig-forest-d);
  --colophon-fg:   var(--pig-cream);
  --colophon-mute: rgba(244, 238, 224, 0.75);
  --colophon-mute: rgb(from var(--pig-cream) r g b / 0.75);
  --colophon-link: var(--pig-amber);
  --colophon-rule: rgba(201, 158, 70, 0.50);
  --colophon-rule: rgb(from var(--pig-amber) r g b / 0.50);
}

:root[data-theme="lamp"],
:root:not([data-theme="day"]):not([data-theme="lamp"]) {
  --colophon-bg: #10231a;
}

/* ------------------------------------------------------------
   TYPE · easing · depth
   ------------------------------------------------------------ */
:root {
  --font-display: "Fraunces", "Fraunces Fallback", Georgia, serif;
  --font-hand:    "Caveat", "Caveat Fallback", "Segoe Script", cursive;
  --font-mono:    "Space Mono", "Space Mono Fallback", "Courier New", monospace;

  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-out:    cubic-bezier(0.22, 1, 0.36, 1);

  /* Depth is fully allocated. Ephemera climb 60→88 as they are
     picked up, so nothing else may sit in that range. */
  --z-content:  1;
  --z-ephemera: 60;   /* …through 88, see modules/ephemera.js */
  --z-chrome:   70;   /* spine + tabs: above content, BELOW the grain,
                         so the grain prints over them on the same sheet */
  --z-lamp:     80;
  --z-speck:    89;
  --z-grain:    90;
  --z-cursor:   100;
  --z-skip:     200;
}

/* ------------------------------------------------------------
   TEXTURE · baked, not live
   ------------------------------------------------------------
   These were four duplicated data-URIs and one live feTurbulence
   filter on a fixed full-viewport <rect>. As a *filter* the noise
   is re-evaluated by the compositor; as a background-image it is
   rasterised once, cached, and tiled. stitchTiles="stitch" makes
   the seams invisible.
   ------------------------------------------------------------ */
:root {
  --noise-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='128' height='128'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.72' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='128' height='128' filter='url(%23g)'/%3E%3C/svg%3E");

  --mask-rough: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.5' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.9 0.25'/%3E%3C/filter%3E%3Crect width='120' height='120' fill='white' filter='url(%23n)'/%3E%3C/svg%3E");
}

}
