/* ==========================================================================
   Astral Sovereignty — the colour system's stylesheet

   core/colours.js decides every colour; this file is the two places a
   declaration cannot reach from where that module writes it, plus the
   not-a-colour half of the colour-blind modes.

   WHAT THE MODULE DOES ON ITS OWN. It writes game.css's tokens (--bg-0,
   --panel, --blue, --text…) straight onto <html> as inline custom properties.
   Inline beats every author rule at that level, including preset-command.css's
   own retune of the same names, so the Desktop and Mobile layouts need nothing
   from this file at all.

   WHY THE MINT LAYOUT NEEDS SECTION 1. concept-mint.css RE-DECLARES its tokens
   on #app, and a declaration on a descendant beats an inherited value however
   that value got there — an inline --cm-panel on <html> is simply overwritten
   inside the scope. So the module publishes the Mint half under a private
   --cs-* name and section 1 re-points the real tokens to it, at a specificity
   (1,2,1) that clears both the base block (0,1,0) and the Astral theme block
   (0,2,0). The literal in each fallback is the DEFAULT scheme's value, so a
   browser with no stored scheme paints the shipped Astral colours rather than
   nothing at all; tests/colours.test.js pins every one of them against
   core/colours.js's own table.

   WHY SECTION 2 EXISTS AT ALL. Colour may never be the only thing carrying a
   meaning. Every status pill in this client is a pill with a word in it and
   every meter states its level in its own title, so the pills and the badges
   are already safe — but a meter is a bar, and under Monochrome three bars that
   differ only in brightness is exactly the failure the mode was turned on to
   avoid. Section 2 is the pattern that makes them tellable apart with no colour
   at all.

   Discipline:
   - Inert with no scheme applied: every rule here is under [data-colours] or
     [data-vision], attributes core/colours.js is the only writer of.
   - No colour literals outside section 1's fallbacks. A colour written into a
     rule is a colour no scheme can reach; the tests fail on one.
   - Loaded LAST of the stylesheets, so inside its own scope it out-ranks the
     preset, the app shell and both mint sheets.
   ========================================================================== */

/* ---------- 1. The Mint half ---------------------------------------------- */

/* Scoped exactly like the two blocks it overrides — the modals and toasts the
   game mounts OUTSIDE #app are siblings of it, and a scheme that stopped at the
   frame would leave every dialog in the previous palette. */
html[data-colours] #app.concept-mint,
html[data-colours] #app.concept-mint ~ dialog.modal,
html[data-colours] #app.concept-mint ~ #toasts {
  --cm-bg: var(--cs-cm-bg, #04060e);
  --cm-bg-1: var(--cs-cm-bg-1, #070b16);
  --cm-bg-2: var(--cs-cm-bg-2, #0a1120);
  --cm-panel: var(--cs-cm-panel, #0e1729);
  --cm-panel-raised: var(--cs-cm-panel-raised, #142137);
  --cm-panel-3: var(--cs-cm-panel-3, #1b2b45);
  --cm-line: var(--cs-cm-line, #2b4a72);
  --cm-line-mid: var(--cs-cm-line-mid, #1c2f4a);
  --cm-line-soft: var(--cs-cm-line-soft, #14233a);
  --cm-edge-ui: var(--cs-cm-edge-ui, #4c6b96);
  --cm-track: var(--cs-cm-track, #22344f);
  --cm-grabber: var(--cs-cm-grabber, #55708f);
  --cm-text: var(--cs-cm-text, #eaf1ff);
  --cm-muted: var(--cs-cm-muted, #b9c8de);
  --cm-text-3: var(--cs-cm-text-3, #9fb3cd);
  --cm-text-4: var(--cs-cm-text-4, #94a9c5);
  --cm-accent: var(--cs-cm-accent, #ff8a1f);
  --cm-accent-ink: var(--cs-cm-accent-ink, #180d00);
  --cm-link: var(--cs-cm-link, #8fc0ff);
  --cm-link-deep: var(--cs-cm-link-deep, #14345c);
  --cm-success: var(--cs-cm-success, #6fd39a);
  --cm-warning: var(--cs-cm-warning, #ffc65a);
  --cm-warning-ink: var(--cs-cm-warning-ink, #2a1c00);
  --cm-danger: var(--cs-cm-danger, #ff8f8c);
  --cm-warning-bg: var(--cs-cm-warning-bg, #33270e);
  --cm-danger-bg: var(--cs-cm-danger-bg, #331c22);
  --cm-success-bg: var(--cs-cm-success-bg, #0f2a20);
  --cm-accent-bg: var(--cs-cm-accent-bg, #5a2e06);
  --cm-link-dim: var(--cs-cm-link-dim, rgba(143, 192, 255, .13));
  --cm-warning-dim: var(--cs-cm-warning-dim, rgba(255, 198, 90, .13));
  --cm-success-dim: var(--cs-cm-success-dim, rgba(111, 211, 154, .13));
  --cm-danger-dim: var(--cs-cm-danger-dim, rgba(255, 143, 140, .12));
  --cm-scrim: var(--cs-cm-scrim, rgba(2, 4, 10, .62));
  --cm-glass: var(--cs-cm-glass, rgba(4, 6, 14, .72));
  --cm-glass-soft: var(--cs-cm-glass-soft, rgba(4, 6, 14, .45));
  --cm-hero-fade: var(--cs-cm-hero-fade, rgba(4, 6, 14, .55));
  --cm-hero-glow: var(--cs-cm-hero-glow, rgba(87, 200, 255, .16));
  --cm-hero-edge: var(--cs-cm-hero-edge, rgba(255, 138, 31, .45));
  --cm-art-ink: var(--cs-cm-art-ink, #ffffff);
  --cm-art-ink-2: var(--cs-cm-art-ink-2, #dfe9fb);
}

/* ---------- 2. Monochrome — pattern, not brightness ------------------------ */

/* The three meter states, told apart by their fill pattern. Diagonal hatching
   for caution, a denser cross-hatch for trouble, flat for everything that is
   fine — so the loudest bar is also the busiest one, at any brightness and in
   any layout. The gradients are painted in currentColor terms (a translucent
   black over the fill the meter already has), so they cost no colour token and
   survive whatever the fill turns out to be.

   Both looks are covered: game.css's .meter for Desktop and Mobile, the kit's
   .cm-meter for Mint. Neither module is touched — the classes are the ones both
   already ship. */
html[data-vision="monochrome"] .meter.warn > i,
html[data-vision="monochrome"] .cm-meter--warn .cm-meter__fill {
  background-image: repeating-linear-gradient(
    135deg,
    rgba(0, 0, 0, .55) 0 3px,
    rgba(0, 0, 0, 0) 3px 6px);
}
html[data-vision="monochrome"] .meter.bad > i,
html[data-vision="monochrome"] .cm-meter--danger .cm-meter__fill {
  background-image:
    repeating-linear-gradient(45deg, rgba(0, 0, 0, .5) 0 2px, rgba(0, 0, 0, 0) 2px 4px),
    repeating-linear-gradient(135deg, rgba(0, 0, 0, .5) 0 2px, rgba(0, 0, 0, 0) 2px 4px);
}
/* An explicitly GOOD meter is the third state and needs its own mark, or "fine"
   and "no state at all" are the same bar. A single wide stripe reads as a
   texture rather than a warning. */
html[data-vision="monochrome"] .cm-meter--good .cm-meter__fill {
  background-image: repeating-linear-gradient(
    90deg,
    rgba(0, 0, 0, .35) 0 1px,
    rgba(0, 0, 0, 0) 1px 5px);
}

/* The icons, too. Every glyph in this client sits beside its own label, so it is
   decoration — but a screen where the only colour left is a row of little blue
   icons is not the mode the player asked for.
   `filter` ON THE IMAGE, never on a container: a filter makes its element a
   containing block for `position: fixed` descendants, which would re-anchor the
   map sheet, the modals and the toast stack to whichever card they happened to
   be inside. An <img> has no such descendants. The photographic art keeps its
   own colours — most of it is a CSS background on a box that DOES have fixed
   descendants, and the Colours card says so rather than promising otherwise. */
html[data-vision="monochrome"] img,
html[data-vision="monochrome"] svg { filter: grayscale(1); }

/* The same distinction on the two other bars that carry a state by fill alone:
   the climate comfort core and the experience bar are both a flat colour in a
   track, and under Monochrome a flat grey in a flat grey track is nothing. */
html[data-vision="monochrome"] .axis-zone {
  background-image: repeating-linear-gradient(
    135deg,
    rgba(0, 0, 0, .4) 0 2px,
    rgba(0, 0, 0, 0) 2px 5px);
}

/* ---------- 3. The Colours card ------------------------------------------- */

/* More -> Colours. Built from the shared vocabulary (.card, .field, .btn, .row)
   with only the things that vocabulary has no word for declared here: a tile
   grid of schemes, the swatch strip on each tile, the colour-well rows and the
   contrast readout. Every colour below is a token — the card is the one surface
   that has to repaint correctly the instant the scheme it is changing changes.
*/
.cs-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: .5rem;
  margin: .2rem 0 .6rem;
}
.cs-tile {
  display: flex; flex-direction: column; align-items: stretch; gap: .35rem;
  min-height: var(--tap);
  padding: .5rem .55rem;
  border: 1px solid var(--line-lit);
  border-radius: var(--rad-sm);
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.cs-tile:hover { border-color: var(--edge-ui); }
.cs-tile[aria-pressed="true"] {
  border-color: var(--tab-current, var(--cyan));
  background: var(--blue-dim);
}
.cs-tile__name { font-weight: 700; font-size: var(--t-sm); display: flex; align-items: center; gap: .3rem; }
/* The tick is the non-colour half of "this one is on": the border changes too,
   but a border is a colour cue and this card of all cards may not rely on one. */
.cs-tile__on { color: var(--tab-current, var(--cyan)); font-weight: 700; }
.cs-swatches { display: flex; gap: 3px; height: 14px; }
.cs-swatches > i {
  flex: 1 1 0; border-radius: 3px; border: 1px solid var(--line-soft); display: block;
}
.cs-tile__hint { font-size: var(--t-xs); color: var(--text-3); }

/* Custom expands IN PLACE, under its own tile, rather than in a sheet: the
   whole point of the picker is that the screen behind it is the preview. */
.cs-custom {
  margin: 0 0 .6rem;
  padding: .6rem .65rem;
  border: 1px solid var(--line);
  border-left: 2px solid var(--tab-current, var(--cyan));
  border-radius: var(--rad-sm);
  background: var(--panel);
}
.cs-well {
  display: flex; align-items: center; gap: .6rem;
  min-height: var(--tap);
  padding: .15rem 0;
}
.cs-well > input[type="color"] {
  flex: none;
  width: var(--tap); height: var(--tap);
  padding: 2px;
  border: 1px solid var(--line-lit);
  border-radius: var(--rad-sm);
  background: var(--panel-2);
  cursor: pointer;
}
.cs-well__text { min-width: 0; }
.cs-well__name { font-size: var(--t-sm); font-weight: 600; }
.cs-well__hint { font-size: var(--t-xs); color: var(--text-3); }
.cs-ratio {
  display: flex; flex-wrap: wrap; gap: .3rem .8rem;
  margin: .45rem 0 .5rem;
  font-size: var(--t-xs);
  color: var(--text-3);
}
.cs-ratio b { color: var(--text-2); font-variant-numeric: tabular-nums; }
.cs-ratio .cs-pass { color: var(--green); }
.cs-ratio .cs-fixed { color: var(--amber); }

/* The vision segment. A radio group drawn as a column of rows, because five
   options with a sentence each do not fit across a 412px phone. */
.cs-vision { display: flex; flex-direction: column; gap: .1rem; }
.cs-vision label {
  display: flex; align-items: flex-start; gap: .5rem;
  min-height: var(--tap);
  padding: .35rem 0;
  font-weight: 400;
}
/* The LABEL is the tap target — full width, 44px tall, and clicking one selects
   its radio — so the control itself only has to be big enough to see. game.css
   deliberately exempts radios from the tap floor (stretching one paints a 44px
   tick, which reads as a bug); 20px is the largest a browser draws honestly. */
.cs-vision input[type="radio"] { flex: none; width: 20px; height: 20px; margin-top: .15rem; }
