/* ============================================================================
   lore-tokens.css — the one palette.
   ----------------------------------------------------------------------------
   Written 6 Sep 2026, after Cory said the membership page "does not match Lore
   itself". He was right, and the cause was not a design decision anyone had
   made. Thirteen pages carried their own copy of the palette, and the copies
   had drifted: seven different page backgrounds, five different accents — three
   separate oranges all claiming to be the brand (#e8833a, #E07B39, #f97316) —
   and a main-app background of #0e1117 against the client pages' #0f1117. One
   hex digit apart. Nobody can name that difference; everybody feels it.

   THE RULE FROM HERE: a page does not define colours. It links this file and
   uses the tokens. If a colour is missing, add it HERE, once.

   HOW THEMING WORKS. The app stamps data-theme="light" on <html> (nav.js, and
   the inline script at the top of each page). No stamp means dark. That is the
   existing mechanism and this file does not change it — deliberately, because
   the point of this pass was to remove drift without moving a single pixel.
   Do not add a prefers-color-scheme block here: the "system" setting is already
   resolved to an explicit stamp in JS, and a media query would fight it.

   THE ALIAS BLOCK at the bottom is why converting a page is safe. Different
   pages grew different names for the same colour — --card and --surface,
   --line and --border, --text-1 and --text. Rather than rewrite hundreds of
   CSS rules (and risk missing one), every name in use is defined here as an
   alias. So a page converts by DELETING its palette and ADDING one link tag.
   Nothing else in the page changes. New work should use the canonical names;
   the aliases exist to retire old ones without a big-bang rewrite.
   ========================================================================== */

:root {
  /* ── Ground and surfaces — NEUTRAL, all of them ───────────────────────────
     This is the change of 20 Sep and the whole point of it. The nine palettes
     this file used to sit under tinted every one of these with the accent hue
     (--border: rgba(78,117,35,0.14), --bg-hover: rgba(78,117,35,0.06), greys
     warmed toward the brand). That is what made Lore read as "a green app"
     rather than an app with a green accent, and it is why the colour had to
     be repainted when you switched workspace.

     Linear and Notion both do the opposite: every surface, border and grey is
     neutral, and the accent is spent only on things that are interactive or
     live. A barely-warm cast is allowed — a 12-point spread across the
     channels at most, which lore-tokens-contrast.test.js enforces — because a
     dead-neutral grey reads cold and Lore is an outdoors product. Anything
     more than that is a tint, and a tint is a brand decision leaking into the
     chrome. */
  --bg:        #111210;   /* the page itself */
  --surface:   #1a1b19;   /* a card sitting on it */
  --surface2:  #222320;   /* something inset within a card */
  --border:    #262824;

  /* ── Type ─────────────────────────────────────────────────────────────── */
  --text:      #f4f4f1;   /* what you read */
  --text2:     #c7c6c1;   /* supporting */
  --text3:     #97948e;   /* labels, captions, the quiet stuff */

  /* ── Meaning ──────────────────────────────────────────────────────────── */
  /* ONE GREEN. The old file kept --green ("good/earned") deliberately apart
     from --accent ("the brand"), which was right while the brand was orange.
     With a green brand the distinction collapses: two greens a few degrees
     apart read as a mistake, not as a meaning. --green is the accent now, and
     status leans on --warn and --danger, which actually differ. Split them
     again by changing this one line, not by hunting through the app. */
  --accent:    #7cc96a;
  --green:     #7cc96a;
  --navy:      #1f3d65;
  --warn:      #e0a33a;
  --danger:    #f0736a;

  /* ── The accent as a SURFACE ──────────────────────────────────────────────
     --accent      the brand as TEXT — a link, an active label. 9.32:1 here.
     --accent-fill the brand as a background — a primary button, a badge.
     --accent-on   what sits on that fill. 7.52:1.

     These now differ BETWEEN THEMES, which the previous version deliberately
     avoided ("a filled button carries its own ground, so the page behind it
     does not matter"). True of contrast, false of appearance: the deep green
     that looks right on a white page goes muddy on a near-black one, and the
     bright green that sings on dark washes out on white. Both pairs clear AA
     on their own; the test proves it for each theme separately. */
  --accent-fill: #6fbf73;
  --accent-on:   #10210f;

  /* "The thing under your cursor" — neutral, deliberately. The palettes used
     to tint this with the accent too. See the note in [data-theme="light"].
     styles.css's name; nav.js bridges --oi-hover to it at runtime. */
  --bg-hover:  rgba(255,255,255,0.05);
}


[data-theme="light"] {
  --bg-hover:  rgba(0,0,0,0.045);
  --bg:        #f7f7f5;   /* warm-neutral, not blue-grey and not pure white */
  --surface:   #ffffff;
  --surface2:  #f1f1ee;
  --border:    #e0dfda;

  --text:      #181715;   /* near-black, never #000 — it reads as a hole */
  --text2:     #403e3a;
  --text3:     #66635d;

  /* The same hue, deep enough to be read on white. The bright green above
     scores 3.2:1 here and cannot be a link. OI's own #84c23f scores 2.15:1 —
     it was never usable as text in any theme, which is why the palette it came
     from had to carry a separate --accent-text to paper over the gap. One
     token per job instead. */
  --accent:    #2b7230;
  --green:     #2b7230;
  --navy:      #1f3d65;
  --warn:      #8a5300;
  --danger:    #b42318;

  --accent-fill: #2f7d32;
  --accent-on:   #ffffff;
}


/* ============================================================================
   ALIASES — older names, kept working. Defined once, in terms of the canonical
   tokens above, so they follow the theme automatically and can never drift.
   ========================================================================== */
:root,
[data-theme="light"] {
  /* THE SOFT WASH behind accent-coloured text — a selected chip, a status
     pill, a secondary button. Six places were writing rgba(232,131,58,.1)
     literally: the retired orange, hardcoded, sitting behind var(--accent)
     text. So a green workspace got green words on an orange ground, which is
     both the wrong brand and the worse contrast — "Upload now" measured
     3.59:1 in dark and 4.39:1 in light, under the 4.5:1 minimum. Derived from
     the accent it follows every palette, and the same button clears AA.

     color-mix has been in every evergreen browser since 2023 and Safari 16.2.
     The rgba() on the line before is what an older phone falls back to, and it
     is the OI green rather than the orange — so even the fallback is not a
     colour we retired. my-photos.html already asked for this name with that
     exact fallback; it was simply never defined. */
  --accent-soft: rgba(127,160,90,.10);
  --accent-soft: color-mix(in srgb, var(--accent) 12%, transparent);

  /* capture.html's naming */
  --card:       var(--surface);
  --line:       var(--border);
  --text-1:     var(--text);
  --text-2:     var(--text2);
  --text-3:     var(--text3);
  --text-4:     var(--text3);
  --ok:         var(--green);

  /* THE ELEVEN THAT LIVED ONLY IN palettes.css (20 Sep).
     Those nine palette blocks each defined these, and nothing else did. When
     the palettes went, anything reading them resolved to nothing — or worse,
     to a stale value from styles.css's own :root, which is how the shell ended
     up painting a white drawer under near-white text. Defined here, once,
     derived from the canonical tokens so they follow the theme. */
  --accent-text:   var(--accent);          /* the accent already IS the text tone */
  --accent-hover:  color-mix(in srgb, var(--accent) 82%, var(--text));
  --bg-panel:      var(--surface);
  --bg-input:      var(--surface2);
  --surface3:      var(--surface2);
  --card-border:   var(--border);
  --text-5:        var(--text3);
  --text-muted:    var(--text3);
  --green-bg:      var(--accent-soft);
  --green-border:  color-mix(in srgb, var(--accent) 28%, transparent);
  /* The topographic wash behind the page. Neutral now rather than a tint of
     whichever workspace you were in — it is chrome, and chrome is neutral. */
  --topo-stroke:   color-mix(in srgb, var(--text3) 14%, transparent);

  /* the main app (styles.css) naming */
  --bg-card:    var(--surface);
  --bg-2:       var(--surface2);
  --bg-3:       var(--surface2);
  --border-2:   var(--border);
  --muted:      var(--text3);

  /* the comms components, which are embedded in more than one page */
  --oi-text:      var(--text);
  --oi-text-2:    var(--text2);
  --oi-text-3:    var(--text3);
  --oi-border:    var(--border);
  --oi-surface:   var(--surface);
  --oi-surface-2: var(--surface2);
  --oi-accent:    var(--accent);
  /* nav.js carries its own stylesheet and reads these four as well. Without
     them the app shell renders with no ground and no hover — which is what
     stopped the member pages from simply loading the nav. (6 Sep) */
  --oi-bg:        var(--bg);
  --oi-surface-3: var(--surface2);
  --oi-text-4:    var(--text3);
  --oi-hover:     var(--bg-hover);
  --bubble-other:     var(--surface2);
  --bubble-ai-bg:     var(--surface2);
  --bubble-ai-border: var(--border);
  --bubble-radius:    16px;
  --bubble-tail:      4px;
  /* Composed shapes — see styles.css for the rule. Both roots must agree;
     test/bubble-shape.test.js asserts they do. */
  --bubble-shape-self:  var(--bubble-radius) var(--bubble-radius) var(--bubble-tail) var(--bubble-radius);
  --bubble-shape-other: var(--bubble-radius) var(--bubble-radius) var(--bubble-radius) var(--bubble-tail);
  --bubble-shape-plain: var(--bubble-radius);
  /* Composer standard — see styles.css. The 12px rounded message-input box.
     Both roots must agree; test/composer-shape.test.js asserts they do. */
  --composer-radius: 12px;
}
