/* Design tokens.
 *
 * Two palettes live here and they are not allowed to mix.
 *
 * THE CHART PALETTE (--series-*, --seq-*, --div-*) is the validated categorical
 * set from the data-viz standard, on its dark surface #1a1a19. Those hexes are
 * not adjustable by eye: the slot order is what makes the set colourblind-safe,
 * and re-stepping one value silently breaks the guarantee for every chart. If a
 * chart needs a colour, it takes the next slot in order.
 *
 * THE TYPE PALETTE (--type-*) is the eighteen Pokemon type colours. These are
 * entity colours, not series colours. Fire is that orange the way Coca-Cola
 * is that red, and a dex that drew Fire in "categorical slot 2" would read as
 * broken to anyone who has played the games.
 *
 * Eighteen hues cannot be made colourblind-safe; grass, bug and the two greens
 * collapse under deuteranopia no matter how they are stepped. So the rule is
 * that a type colour NEVER carries meaning on its own. Every place one appears
 *. Badge, treemap cell, filter chip, legend, the type's name appears with
 * it in text. The colour is recognition, the label is the information.
 *
 * That is why the analytics charts do not colour their series by type. Where a
 * chart genuinely needs to distinguish types (the treemap, the type summary),
 * every mark is directly labelled and the colour rides along.
 */

:root {
  color-scheme: dark;

  /* ---------------------------------------------------------- surfaces */
  --page:            #0d0d0d;   /* the plane the whole app sits on */
  --surface:         #1a1a19;   /* chart surface; the validator's dark default */
  --surface-raised:  #232322;   /* cards sitting above the chart surface */
  --surface-sunken:  #121211;   /* wells, list backgrounds, the 3D stage */
  --surface-hover:   #2c2c2a;

  /* ---------------------------------------------------------------- ink
   *
   * Every step is measured against --surface-raised (#232322), the lightest
   * background any of them lands on and therefore the worst case. The old
   * ramp was set by eye and two steps of it did not survive measurement:
   * muted came out at 4.38:1. Under the 4.5:1 AA minimum, and faint at
   * 2.31:1, which is a non-text ratio being used for --text-3xs captions.
   *
   * Contrast is not a style choice you can spend on subtlety. The hierarchy
   * is still four clear steps; it just now lives entirely inside the range
   * where the smaller step is a quieter grey rather than an unreadable one. */
  --ink:             #ffffff;   /* 15.9:1 on raised */
  --ink-secondary:   #c3c2b7;   /*  8.8:1 */
  --ink-muted:       #9d9b93;   /*  5.6:1. Axis labels, ticks, captions */
  --ink-faint:       #8b8a83;   /*  4.5:1, the floor, not a decorative grey */

  /* -------------------------------------------------------------- lines */
  --grid:            #2c2c2a;   /* hairline gridlines */
  --axis:            #383835;   /* baselines and axes */
  --border:          rgba(255, 255, 255, 0.10);
  --border-strong:   rgba(255, 255, 255, 0.18);

  /* ------------------------------------------------------------- chrome */
  /* Pokedex red. Brand and device only. Never a chart series, because a
   * reader who sees it on a bar will read "this bar is the important one". */
  --brand:           #dc0a2d;
  --brand-dim:       #a30820;
  --brand-glow:      rgba(220, 10, 45, 0.35);
  /* A selected row, rather than a selected button: the brand at low strength,
   * so a filled list row still reads as a list row. Full --brand behind a
   * 48px row of body text is a banner, not a selection. Measured at 8.5:1 for
   * secondary ink and 15.2:1 for white, so nothing on it needs restating. */
  --brand-wash:      #47131d;
  --screen:          #98cb98;   /* the classic green Pokedex screen */
  --screen-dark:     #2c4a2c;

  /* --------------------------------------------- categorical (validated) */
  /* Dark-mode steps. Order is the colourblind-safety mechanism: assign in
   * sequence, never cycle, never reorder. Slots 1-3 are the only three safe
   * for scatter and other all-pairs forms. */
  --series-1: #3987e5;   /* blue    */
  --series-2: #d95926;   /* orange  */
  --series-3: #199e70;   /* aqua    */
  --series-4: #c98500;   /* yellow  */
  --series-5: #d55181;   /* magenta */
  --series-6: #008300;   /* green   */
  --series-7: #9085e9;   /* violet  */
  --series-8: #e66767;   /* red     */

  /* ------------------------------------------------- sequential (blue) */
  --seq-100: #cde2fb;
  --seq-200: #9ec5f4;
  --seq-300: #6da7ec;
  --seq-400: #3987e5;
  --seq-500: #256abf;
  --seq-600: #184f95;
  --seq-700: #0d366b;

  /* --------------------------------------------------------- diverging */
  /* Type effectiveness is polarity around 1x, not magnitude: a multiplier is
   * either good for the defender, neutral, or bad. Two hues either side of a
   * neutral grey is exactly that shape. Blue reads as "resisted", red as
   * "super effective", and 1x genuinely looks like nothing. */
  --div-neg-3: #0d366b;   /* 0x    immune          */
  --div-neg-2: #256abf;   /* 0.25x doubly resisted */
  --div-neg-1: #6da7ec;   /* 0.5x  resisted        */
  --div-mid:   #383835;   /* 1x    neutral         */
  --div-pos-1: #e66767;   /* 2x    weak            */
  --div-pos-2: #c23b3b;   /* 4x    doubly weak     */

  /* ------------------------------------------------------------- status */
  --good:     #0ca30c;
  --warning:  #fab219;
  --serious:  #ec835a;
  --critical: #d03b3b;

  /* ------------------------------------------------- the same hues, as ink
   *
   * A palette validated for fills is not automatically valid for type. Every
   * colour above was chosen to be distinguishable as a block of area in a
   * chart, where WCAG asks 3:1 of it. Set as 10px uppercase text those same
   * hues run 3.3-4.3:1 against the card, under the 4.5:1 text minimum, and
   * a 10px glyph is the thinnest possible sample of a colour, the case where
   * a shortfall hurts most.
   *
   * So the hue carries over and the lightness does not. Same identity, same
   * meaning, measured for text. Use these any time a palette colour is
   * applied to a font rather than to a rectangle. */
  --ink-blue:     #6fa9ee;   /* 6.6:1 on raised. Was --series-1  at 4.3 */
  --ink-orange:   #eb8a5e;   /* 6.7:1. Was --series-2  at 4.1 */
  --ink-red:      #e97b7b;   /* 5.7:1. Was --critical  at 3.3 */
  --ink-green:    #3fc23f;   /* 6.4:1. Was --good      at 4.7 */

  /* --------------------------------------------------------------- type */
  --type-normal:   #9099a1;
  --type-fighting: #ce4069;
  --type-flying:   #8fa8dd;
  --type-poison:   #ab6ac8;
  --type-ground:   #d97746;
  --type-rock:     #c7b78b;
  --type-bug:      #90c12c;
  --type-ghost:    #5269ac;
  --type-steel:    #5a8ea1;
  --type-fire:     #ff9c54;
  --type-water:    #4d90d5;
  --type-grass:    #63bb5b;
  --type-electric: #f3d23b;
  --type-psychic:  #f97176;
  --type-ice:      #74cec0;
  --type-dragon:   #0a6dc4;
  --type-dark:     #5a5366;
  --type-fairy:    #ec8fe6;

  /* --------------------------------------------------------- typography */
  --font: system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Numbers only. Stat columns and axis ticks have to align vertically, and
   * proportional figures make a column of three-digit stats look ragged. */
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "Consolas", monospace;

  /* Every size is a multiple of --ui-scale, which the reader controls from the
   * settings menu (see app.js). A dex is a dense thing full of 10px labels;
   * "make the text bigger" should be one control, not a browser zoom that also
   * blows up the sprites and reflows the whole grid.
   *
   * The two smallest steps exist because a lot of chart furniture and card
   * captions were hard-coded at 9px and 10px, which put them outside any such
   * control. They are tokens now so they scale with everything else.
   *
   * THE RAMP MOVED UP. It started at 10/11/12 for the three smallest steps,
   * which is chart-furniture sizing applied to text people actually read.
   * Table rows, captions, the trainer lists. Dense is not the same as small,
   * and a dex can be dense at 13px.
   *
   * The bottom of the ramp moved most (10 -> 12, a fifth larger) and the top
   * barely moved, because the headings were never the problem. 100% is now
   * this larger set; the slider reaches down to 75% for anyone who wants the
   * old density back, which is a choice rather than a default. */
  --ui-scale: 1;

  --text-3xs:  calc(12px * var(--ui-scale));
  --text-2xs:  calc(13px * var(--ui-scale));
  --text-xs:   calc(14px * var(--ui-scale));
  --text-sm:   calc(15px * var(--ui-scale));
  --text-base: calc(16px * var(--ui-scale));
  --text-md:   calc(18px * var(--ui-scale));
  --text-lg:   calc(22px * var(--ui-scale));
  --text-xl:   calc(30px * var(--ui-scale));
  --text-2xl:  calc(42px * var(--ui-scale));

  /* ------------------------------------------------------------ spacing */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;

  --radius-sm: 4px;
  --radius:    8px;
  --radius-lg: 14px;

  --shadow:    0 2px 8px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 12px 40px rgba(0, 0, 0, 0.55);

  /* Header and analytics bar heights, referenced by the 3D stage so the canvas
   * can size itself without measuring the DOM on every frame. */
  --header-h: 56px;
  --rail-w:   264px;
  --detail-w: 340px;
}

/* The site is designed dark, the Pokedex device, the screen glow and the
 * chart surface are all built for it. A light mode here would not be a token
 * swap, it would be a different design, so rather than ship a broken automatic
 * flip the page commits to dark and says so via color-scheme above. */
