/* ==========================================================================
   Cartographic Projection — tokens.
   ==========================================================================

   The structural stylesheet is essay-kit's base.css, loaded first. Everything
   below is this site's identity and nothing else.

   Light mode is the warm paper of a printed atlas; dark mode is the ink-blue of
   a nautical chart rather than a generic night theme. The accent set is the
   Okabe–Ito qualitative palette, darkened where it has to carry text, because it
   holds up under the two common colour vision deficiencies — a claim the sibling
   site colour-science-perception.com measures rather than repeats.

   The semantic roles are the quantities this subject actually distinguishes.
   Angular deformation and areal error are the two independent ways a map can be
   wrong, and they are given two colours that stay distinct under greyscale and
   under dichromacy, because several figures ask the reader to compare them
   directly. Everything true of the sphere is drawn in one colour and everything
   true of the plane in another, so a figure showing both never has to explain
   which is which.
   ========================================================================== */

:root {
  --paper:   #f7f5f1;
  --paper-2: #f0ede7;
  --paper-3: #e3ded4;
  --ink:     #17242c;
  --ink-2:   #44535c;
  --ink-3:   #5c6a73;
  --rule:    #d2cabc;
  --rule-2:  #e8e3da;
  --rule-3:  #e8e3da;

  /* Semantic roles, contrast-safe against --paper. */
  --c-a: #0f5e7a;   /* the sphere: graticules, great circles, what is true */
  --c-b: #9e4600;   /* the plane: the projected image, what the map shows */
  --c-c: #00695a;   /* a quantity that came out right — no distortion here */
  --c-d: #7a5b00;   /* a measured value, and the axes that carry one */
  --c-e: #8a4f86;   /* construction: developable surfaces, tangent lines */
  --c-warn: #b3261e; /* a claimed property that failed its test */

  /* Data series inside figures — canonical Okabe–Ito. Not for text. */
  --series-1: #0072b2;
  --series-2: #d55e00;
  --series-3: #009e73;
  --series-4: #e69f00;
  --series-5: #56b4e9;
  --series-6: #cc79a7;
  --series-7: #f0e442;

  /* The two independent distortions. Kept apart deliberately: several figures
     plot both on one pair of axes and the reader has to tell them apart. */
  --d-angle: #0072b2;
  --d-area:  #d55e00;

  --fig-ink:   var(--ink);
  --fig-soft:  #6d7a82;
  --fig-faint: #cdc6ba;

  --tint: 15%;
  --tint-strong: 30%;

  --font-body: Georgia, "Nimbus Roman", "Liberation Serif", "Times New Roman", serif;
  --font-display: var(--font-body);
  --font-ui: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --measure: 34rem;
  --radius: 3px;
  --shadow: 0 1px 2px rgb(23 36 44 / 8%), 0 8px 24px -14px rgb(23 36 44 / 28%);

  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:   #101a20;
    --paper-2: #16232a;
    --paper-3: #1f2f38;
    --ink:     #e7eef1;
    --ink-2:   #b2c0c7;
    --ink-3:   #98a7af;
    --rule:    #2c3d47;
    --rule-2:  #1a272e;
    --rule-3:  #1a272e;

    --c-a: #56b4e9;
    --c-b: #e69f00;
    --c-c: #3fcfa5;
    --c-d: #f0e442;
    --c-e: #cc79a7;
    --c-warn: #ff8a80;

    --fig-ink:   #e7eef1;
    --fig-soft:  #93a2aa;
    --fig-faint: #2f3f49;

    --tint: 22%;
    --tint-strong: 38%;
    --shadow: 0 1px 2px rgb(0 0 0 / 46%), 0 12px 34px -16px rgb(0 0 0 / 78%);
  }
}

:root[data-theme="dark"] {
  --paper:   #101a20;
  --paper-2: #16232a;
  --paper-3: #1f2f38;
  --ink:     #e7eef1;
  --ink-2:   #b2c0c7;
  --ink-3:   #98a7af;
  --rule:    #2c3d47;
  --rule-2:  #1a272e;
  --rule-3:  #1a272e;

  --c-a: #56b4e9;
  --c-b: #e69f00;
  --c-c: #3fcfa5;
  --c-d: #f0e442;
  --c-e: #cc79a7;
  --c-warn: #ff8a80;

  --fig-ink:   #e7eef1;
  --fig-soft:  #93a2aa;
  --fig-faint: #2f3f49;

  --tint: 22%;
  --tint-strong: 38%;
  --shadow: 0 1px 2px rgb(0 0 0 / 46%), 0 12px 34px -16px rgb(0 0 0 / 78%);
}

/* --- site-specific roles -------------------------------------------------- */

/* The graticule. Meridians and parallels are drawn separately because several
   figures need to say something about one family and not the other. */
.fig-svg .meridian { stroke: var(--c-a); stroke-width: 1.1; fill: none; opacity: 0.75; }
.fig-svg .parallel { stroke: var(--c-a); stroke-width: 1.1; fill: none; opacity: 0.45; }
.fig-svg .equator  { stroke: var(--c-a); stroke-width: 2; fill: none; }
.fig-svg .prime-meridian { stroke: var(--c-a); stroke-width: 2; fill: none; }
.fig-svg .outline  { stroke: var(--ink); stroke-width: 1.6; fill: none; }
.fig-svg .graticule-fill { fill: color-mix(in oklab, var(--c-a) 6%, var(--paper-2)); stroke: none; }

/* Coastlines. Deliberately quiet — they are context for the distortion, not the
   subject, and a heavy coastline turns every figure into a map of the world
   rather than a picture of what the projection did to it. */
.fig-svg .coast { stroke: var(--ink-3); stroke-width: 0.8; fill: none; }
.fig-svg .land  { fill: color-mix(in oklab, var(--ink) 8%, var(--paper-2)); stroke: none; }
.fig-svg .land-marked { fill: color-mix(in oklab, var(--c-b) 26%, var(--paper-2)); stroke: var(--c-b); stroke-width: 1; }

/* Tissot's indicatrix. The ellipse is the whole point of this site, so it is
   given weight, and the circle it would be on an undistorted map is drawn
   underneath it for comparison. */
.fig-svg .indicatrix { fill: color-mix(in oklab, var(--d-angle) 20%, transparent); stroke: var(--d-angle); stroke-width: 1.5; }
.fig-svg .indicatrix-true { fill: none; stroke: var(--fig-soft); stroke-width: 1; stroke-dasharray: 3 3; }
.fig-svg .indicatrix-axis { stroke: var(--d-angle); stroke-width: 1.2; fill: none; }
.fig-svg .indicatrix-big { fill: color-mix(in oklab, var(--d-area) 22%, transparent); stroke: var(--d-area); stroke-width: 1.5; }

/* The two distortions, kept visually separate everywhere they appear. */
.fig-svg .angle-line { stroke: var(--d-angle); stroke-width: 2; fill: none; }
.fig-svg .area-line  { stroke: var(--d-area); stroke-width: 2; fill: none; }
.fig-svg .angle-fill { fill: color-mix(in oklab, var(--d-angle) var(--tint), var(--paper-2)); stroke: none; }
.fig-svg .area-fill  { fill: color-mix(in oklab, var(--d-area) var(--tint), var(--paper-2)); stroke: none; }

/* A property that was claimed and did not hold. */
.fig-svg .failed { stroke: var(--c-warn); stroke-width: 2; fill: none; }
.fig-svg .failed-fill { fill: color-mix(in oklab, var(--c-warn) 18%, var(--paper-2)); stroke: var(--c-warn); stroke-width: 1.2; }
.fig-svg text.failed { fill: var(--c-warn); stroke: none; }
.fig-svg .passed-fill { fill: color-mix(in oklab, var(--c-c) 18%, var(--paper-2)); stroke: var(--c-c); stroke-width: 1.2; }

/* Paths on the sphere: the shortest one, and the one with a constant bearing. */
.fig-svg .great-circle { stroke: var(--c-c); stroke-width: 2.4; fill: none; }
.fig-svg .rhumb { stroke: var(--c-b); stroke-width: 2.2; fill: none; stroke-dasharray: 7 4; }
.fig-svg .waypoint { fill: var(--ink); stroke: var(--paper); stroke-width: 1.4; }

/* Developable surfaces and the constructions that generate a projection. */
.fig-svg .developable { stroke: var(--c-e); stroke-width: 1.6; fill: none; }
.fig-svg .developable-fill { fill: color-mix(in oklab, var(--c-e) 10%, var(--paper-2)); stroke: var(--c-e); stroke-width: 1.2; }
.fig-svg .tangent { stroke: var(--c-e); stroke-width: 1.6; fill: none; stroke-dasharray: 5 4; }
.fig-svg .ray { stroke: var(--fig-soft); stroke-width: 1; fill: none; stroke-dasharray: 2 3; }

/* A measured quantity under test. */
.fig-svg .measured { stroke: var(--c-d); stroke-width: 2.2; fill: none; }

/* Axes and general furniture. */
.fig-svg .axis    { stroke: var(--fig-soft); stroke-width: 1.4; fill: none; }
.fig-svg .grid    { stroke: var(--fig-faint); stroke-width: 0.9; }
.fig-svg .soft    { stroke: var(--fig-soft); stroke-width: 1.2; fill: none; }
.fig-svg .faint   { stroke: var(--fig-faint); stroke-width: 1; fill: none; }
.fig-svg .dot-a   { fill: var(--c-a); stroke: none; }
.fig-svg .dot-b   { fill: var(--c-b); stroke: none; }
.fig-svg .dot-c   { fill: var(--c-c); stroke: none; }
.fig-svg .dot-d   { fill: var(--c-d); stroke: none; }
.fig-svg .dot-e   { fill: var(--c-e); stroke: none; }
.fig-svg .dot-warn{ fill: var(--c-warn); stroke: none; }
.fig-svg .fill-a  { fill: color-mix(in oklab, var(--c-a) var(--tint), var(--paper-2)); }
.fig-svg .fill-b  { fill: color-mix(in oklab, var(--c-b) var(--tint), var(--paper-2)); }
.fig-svg .fill-c  { fill: color-mix(in oklab, var(--c-c) var(--tint), var(--paper-2)); }
.fig-svg .fill-d  { fill: color-mix(in oklab, var(--c-d) var(--tint), var(--paper-2)); }
.fig-svg text.mono { font-family: var(--font-mono); }

/* A label sitting over a filled region gets a real plate, not a stroke halo.
   A halo drawn with paint-order is legible to a reader and invisible to
   svg_check, which samples the fill beneath the glyph. Fleet-wide lesson. */
.fig-svg .plate { fill: var(--paper); stroke: none; opacity: 0.92; }

/* A diagram <text> must not inherit the root stroke, or every label is drawn
   twice and reads as bold mud. Fleet-wide gotcha, cheap to state, easy to lose. */
.fig-svg text { stroke: none; }

/* A rule under section headings. */
.section-head::after { border-top-style: solid; }

/* --- dragging a parameter -------------------------------------------------
   The natural draggable axis here is position on the map: move a point and the
   indicatrix at that point changes. Every frame was produced at build time by
   the same generator, so every frame passed the same assertions.

   The cost is controllable in a way it was not for the molecular site, where 19
   frames of a 640-polygon mesh produced 7.7 MB pages. Here the MAP STAYS STILL
   and only the marker and one ellipse move, so a frame is a few hundred bytes.
   Any new draggable figure must keep that property. */
.drag-row { margin: 0.6rem 0 0; display: grid; gap: 0.35rem; }
.drag-slider { width: min(28rem, 100%); accent-color: var(--c-a); cursor: ew-resize; }
.drag-slider:focus-visible { outline: 2px solid var(--c-a); outline-offset: 3px; }
.drag-readout {
  margin: 0; font: 0.8rem/1.4 var(--font-ui); color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.drag-note { margin: 0; font: 0.74rem/1.4 var(--font-ui); color: var(--ink-3); }
