/* tokens.css -- Both color palettes, the type scale, the spacing and layout tokens, and the view-transition setup for the theme swap.
 *
 * Part 1 of 9. These files were one style.css and are still one
 * stylesheet: equal-specificity rules resolve by document order, so the
 * <link> tags in every page must stay in this order and nothing may move
 * between files without checking what it lands after.
 *   tokens.css -> layout.css -> type.css -> prose.css -> charts.css -> sources.css -> paper.css -> interactive.css -> home.css
 *
 * See site/README.md for the rules that govern all of them. */

/* Styling for the plain-language site.
 *
 * Three rules govern everything here:
 *
 * 1. Two modes, each validated separately. The page used to commit to a white
 *    surface on the argument that one surface is the one the charts were
 *    checked against. That argument was right about the requirement and wrong
 *    about the conclusion: the answer is to check the second surface too, not
 *    to refuse to have one. So there are two complete palettes below, and the
 *    dark one is not the light one dimmed -- the series hues are re-picked for
 *    a dark ground and re-run through the same contrast and color-vision
 *    checks. Nothing in the rest of this file names a color directly; if you
 *    are about to write a hex value outside the two token blocks, you are about
 *    to break one of the modes.
 *
 * 2. Color is earned, not sprinkled. Each section carries an accent hue used
 *    for its rule, its highlighted figures, and its pull-quote -- so color
 *    marks where you are in the argument. The charts draw from the validated
 *    series slots and nothing else; a decorative accent never becomes a data
 *    color, and a data color never becomes decoration.
 *
 * 3. Color never carries meaning alone. The two scatters encode group by
 *    color AND plant by marker shape, every other chart puts its categories on
 *    an axis, and every chart ships a table view. The manuscript's own palette
 *    (matplotlib Set2) fails color-vision checks -- RedClover and Ragweed are
 *    indistinguishable under protanopia -- which is why this does not reuse it.
 */

/* --- The two typefaces ----------------------------------------------------
 *
 * Work Sans for headings, Lora for prose. Both are SIL Open Font Licence and
 * both are served from this origin rather than from Google, for three reasons
 * that all matter more than the twenty lines it costs: a font request to a
 * third party tells that third party who is reading this page and from where;
 * a site whose whole argument is that nothing on it can drift should not have
 * its type depend on a host it does not control; and a self-hosted woff2 on
 * the same connection beats a cross-origin one that must open a new one.
 *
 * Variable fonts, one file per family per style, so 400 through 700 all come
 * out of the same download -- six files and 201 KB in total, of which a reader
 * of English fetches the two `latin` ones and never asks for the rest.
 *
 * `font-display: swap`: the page paints immediately in the fallback and
 * re-flows when the face lands. The alternative, `block`, hides the text for
 * up to three seconds, and a page of invisible prose is a worse failure than
 * a page whose prose shifts once.
 *
 * The `unicode-range` lines are load-bearing, not decoration -- they are what
 * lets the browser skip the latin-ext file until the page actually asks for a
 * character in it, which on these pages means the ø in Øvreås and little else.
 */
@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(../fonts/work-sans-normal-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(../fonts/work-sans-normal-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Lora';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(../fonts/lora-normal-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Lora';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url(../fonts/lora-normal-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Lora';
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  src: url(../fonts/lora-italic-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Lora';
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  src: url(../fonts/lora-italic-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Page-to-page navigation cross-fades rather than blanking to white. The three
 * pages share a bar, a column width and a palette, so a hard reload throws that
 * continuity away for no reason. One line; browsers without it navigate exactly
 * as before. */
/* Switched off 2026-08-18 at the author's request; set back to `auto` to
 * restore the page-to-page cross-fade. */
@view-transition { navigation: none; }

/* What survives a page change, by name.
 *
 * A plain cross-fade dissolves the whole window at once, which is honest but
 * says nothing about what the two pages have in common -- and these five pages
 * have a great deal in common. Naming an element takes it out of the fade and
 * gives it its own animation between where it was and where it lands, so the
 * bar holds still, the section map holds still, and the page title travels.
 *
 * Every name here must be unique *within a document at the moment of capture*.
 * Two elements sharing one name aborts the entire transition -- not just that
 * pair -- which is why `page-hero` is claimed at click time by meta.js rather
 * than written onto the doors here: all three doors carry it, and all three
 * carrying it at once would take the whole effect down.
 *
 * A browser without view transitions ignores every line of this and navigates
 * exactly as it did before. */
.hero { view-transition-name: page-hero; }
.toc  { view-transition-name: page-nav; }

/* The hero is a block of prose changing into a different block of prose, so it
 * is given longer than the default and eased -- at the default 250ms linear it
 * reads as a flicker rather than as one page becoming another. */
::view-transition-group(page-hero) { animation-duration: 0.42s; }
::view-transition-old(page-hero),
::view-transition-new(page-hero) {
  animation-duration: 0.42s;
  animation-timing-function: cubic-bezier(0.22, 0.68, 0.3, 1);
}

/* The section map is a different list on every page it appears on, so its two
 * snapshots have nothing to morph between -- it should hold its position and
 * change its contents, not stretch from eleven rows to eighteen. */
::view-transition-group(page-nav) { animation-duration: 0.3s; }

:root {
  color-scheme: light;

  /* --- Type ---------------------------------------------------------------
   *
   * Two families, and which one a thing wears says what kind of thing it is.
   * Work Sans, bold and tightly tracked, is for headings, the bar, and every
   * label that names rather than argues. Lora is for anything making an
   * argument: body copy, ledes, captions, caveats.
   *
   * The system stacks behind each are what a reader sees for the first few
   * hundred milliseconds, so they are chosen to be close in width rather than
   * merely available -- a fallback that sets much wider than the real face
   * makes the swap read as the page breaking. */
  --font-display: 'Work Sans', ui-sans-serif, system-ui, 'Helvetica Neue', Arial, sans-serif;
  --font-body: 'Lora', ui-serif, Georgia, 'Times New Roman', serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Headings are set tight. Work Sans at display sizes opens up noticeably
   * between letters, and the negative tracking is what makes a headline read
   * as one object rather than as a row of words. Stated once so the whole
   * scale stays in proportion instead of being guessed per heading. */
  --track-display: -0.02em;

  /* --- The type scale -----------------------------------------------------
   *
   * Six steps, and nothing on this site may set a size that is not one of
   * them.
   *
   * This replaces twelve. A census of one page found font sizes at 12.3,
   * 13.4, 14.6, 15.7, 16.8, 17.9, 19, 20.2, 24.2, 31.4, 44.8 and 98.6px --
   * six of them inside a 5.6px band -- across 26 distinct size/weight/family
   * combinations. Every one of those values was individually defensible,
   * which is exactly the problem: they were chosen locally, one component at
   * a time, so none of them was derived from any other. A page assembled that
   * way has no scale, and a reader sees that as a page nobody set.
   *
   * The ratio is roughly 1.15 between the two apparatus sizes and widens
   * toward the top, which is how a text face behaves: the difference between
   * 15px and 17px matters, and the difference between 44px and 47px does not.
   *
   *   1  apparatus -- the bar, legends, axis labels, table cells, badges
   *   2  small     -- captions, buttons, asides, notes, tooltips
   *   3  body      -- running prose, h3, anything argued at reading size
   *   4  lede      -- the standfirst, pull quotes, the conclusion line
   *   5  h2        -- section titles
   *   6  h1        -- page titles, and the one display number a page may carry
   *
   * The fluid part is declared here and only here. Two of these steps grow
   * with the viewport, because display type needs a steeper curve than the
   * root font size gives it -- but that curve is stated once, in the scale,
   * rather than re-invented as a clamp() inside each heading rule. A rule
   * anywhere else in these files that writes its own clamp() is a bug. */
  --size-1: 0.8125rem;
  --size-2: 0.9375rem;
  --size-3: 1.0625rem;
  --size-4: 1.3125rem;
  --size-5: clamp(1.45rem, 3.4vw, 1.75rem);
  --size-6: clamp(1.9rem, 5vw, 2.6rem);

  /* Three, for the same reason. There were seven, between 1 and 1.65, with no
   * relation to each other -- and leading is the one typographic decision a
   * reader feels without being able to name. Display type sets solid, labels
   * and captions set snug, prose sets open. */
  --lh-tight: 1.1;
  --lh-snug: 1.35;
  --lh-body: 1.6;

  /* --- The spacing scale --------------------------------------------------
   *
   * Seven steps, ratio about 1.5, replacing 38 hand-picked values that
   * included 0.55, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.05, 1.1, 1.15,
   * 1.2 and 1.25rem -- twelve numbers inside two thirds of a rem, none of
   * them distinguishable from its neighbors and all of them adding up to a
   * page with no rhythm.
   *
   * These govern the vertical rhythm and the padding inside blocks. They do
   * NOT govern measurements: a 3px rule, a 9px node, the bar's height, the
   * clearance an anchor needs under a sticky bar, and the negative margin
   * that carries a sidenote into the margin are all sizes of things rather
   * than distances between them, and rounding them to a rhythm step would be
   * a different and worse mistake. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1.25rem;
  --space-5: 2rem;
  --space-6: 3rem;
  --space-7: 4.5rem;

  /* --- Shape --------------------------------------------------------------
   *
   * Square, for the page's chrome: tabs, menus, tooltips, dialogs and buttons
   * all take this token and stay sharp. The exceptions are content, not
   * chrome, and are set explicitly where they live (2026-08-19, at the
   * author's request): the photographs, the front-page cards, the pinned
   * figure and the tinted callout boxes round to 0.5rem, because they are
   * things placed on the paper rather than the machinery around it.
   *
   * `--radius-round` is for things that are genuinely circles -- the arrow
   * discs, the section-map dots -- and nothing else. */
  --radius: 0;
  --radius-round: 999px;

  /* Paper, not screen-white. The whole page carries a faint warm cast now --
   * the ground is the color of uncoated stock, the panels the color of
   * linen -- because the subject is a field and a pure #ffffff ground is the
   * one surface in the world that has nothing living on it. The shift is
   * small on purpose: large enough to read as warm beside a browser's white
   * chrome, small enough that the charts validated against a near-white
   * surface are still validated. */
  --surface:        #fbfaf5;
  --surface-raised: #f1eee4;
  --border:         #ded8ca;
  /* Very dark, and green rather than neutral. Pure black on pure white was
   * the previous scheme's whole argument and it is what made the page read as
   * institutional; this is nearly as dark (17.5:1 on the paper, against 21:1
   * for black) and carries the same weight in a body of text, but it belongs
   * to the same world as the greens beside it instead of ruling over them. */
  --text-primary:   #12160f;
  --text-secondary: #3d4436;
  --text-muted:     #63685b;

  /* What a tint is mixed *into*. Every soft accent wash on this page is
   * `color-mix(in oklab, var(--accent) N%, var(--tint-base))`, and it used to
   * name `white` outright -- which in dark mode produces a pale bar on a dark
   * page rather than a faint one, the accent washing toward the wrong end.
   * Naming the base makes each of those mixes follow the surface. */
  --tint-base: var(--surface);

  /* How far an accent wash is pushed. Every soft tint on the page is written at
   * the percentage that looks right on white and multiplied by this, because a
   * 6% wash that is a barely-there hint against white vanishes outright against
   * near-black -- a dark surface needs a larger fraction of the accent to shift
   * by the same perceptual amount. One number, so the tints stay in proportion
   * to each other across both modes instead of being re-tuned fourteen times. */
  --tint-strength: 1;

  /* How much of the photographic backdrop shows through the paper. The image
   * is a sharp grayscale photograph of the farm gate (media/backdrop-1600) and
   * sits behind everything at this opacity, so on the light palette it reads
   * as a faint print in the paper rather than a picture. Lower on the dark
   * palette, where the same opacity would glow. Tuned by eye, 2026-08-18. */
  --backdrop-opacity: 0.16;

  /* The surface again, as bare channels, for the two places that need it at
   * partial alpha: the bottom fade and the dialog backdrop. `rgb()` cannot take
   * a hex and an alpha together, and mixing to `transparent` bands gray (see
   * the fade). This is the same color as --surface and must be kept so. */
  --surface-rgb: 251 250 245;

  /* Shadows are cast by light. On a dark ground a black shadow is invisible and
   * an elevated panel loses its edge, so the depth is carried by a stronger
   * border there and the shadow is only deepened, never inverted -- a light
   * "glow" would read as the panel emitting rather than floating. */
  --shadow-soft: 0 4px 16px rgb(0 0 0 / 0.13);
  --shadow-lift: 0 18px 50px rgb(0 0 0 / 0.18);
  --scrim: rgb(12 12 12 / 0.4);

  /* Chart series: water, clay, leaf. Re-picked for the warm palette and re-run
   * through the whole check rather than eyeballed against it. Every one
   * passes: lightness band, chroma floor, adjacent CVD separation (worst 10.2
   * ΔE deutan, 27.1 tritan), normal vision (worst 24.4), and 3:1 against the
   * surface.
   *
   * The single hard constraint here is the one that kills most earthy
   * palettes. Deutan vision collapses the red-green axis, so a clay and a leaf
   * green of similar depth land 2-4 ΔE apart -- five candidate sets mixed from
   * genuinely soil-like hues failed on exactly that pair, and several also
   * fell under the chroma floor and read as gray. What survives is a clay
   * pushed toward red and a green kept fresh rather than olive: still the
   * colors of a field, but far enough apart to be told apart.
   *
   * Slot 1 doubles as "non-legume", slot 2 as "legume". */
  --series-1: #2F6096;
  --series-2: #B24A26;
  --series-3: #45A06B;
  --series-neutral: #8b8a80;

  --grid: #e8e3d7;

  /* Decorative accents. Not data colors -- these never appear in a chart.
   *
   * Every hue here is named for something that is actually out there in the
   * field the samples came from: forest, lichen, standing water, bark, the
   * clay in the subsoil, beet, dusk, thistle. They are deep rather than
   * bright, which is what keeps a page wearing eight of them from reading as
   * a paintbox -- and every one clears 6.8:1 on the paper, so an accent can
   * carry small text and a rule, a dot and a caption all take the same token
   * without being checked separately.
   *
   * Green leads. It is the site's own color now, and the section that opens
   * each page should be wearing it. */
  --accent-green:   #2F5D3A;
  --accent-slate:   #3C4A38;
  --accent-blue:    #1F5166;
  --accent-amber:   #7A4E12;
  --accent-red:     #8C3A24;
  --accent-plum:    #6B3350;
  --accent-violet:  #4A3F6B;
  --accent-magenta: #8A3358;
  /* Kept as an alias so nothing that still names the old orange breaks; it
   * resolves to the clay, which is the warm slot on this page now. */
  --accent-orange:  var(--accent-red);

  --accent: var(--accent-green);

  /* The green at the strength the chrome needs it: on the dark bar, where the
   * light-mode forest is too deep to read against the pine behind it. */
  --accent-on-dark: #8FBE72;

  /* The brand mark's three horizons: sun-warmed surface, root zone, mineral
   * subsoil. A picture rather than an accent, so they take no part in the
   * rotation -- and, unlike everything else here, they are NOT re-picked for
   * dark mode. The mark only ever sits on the bar, the bar is the same pine in
   * both modes, and a mark that changed color between two identically
   * colored bars was a real fault in the version this replaces.
   *
   * favicon.svg carries the same three values and must be changed with them;
   * they are duplicated there rather than shared because a favicon cannot read
   * CSS. */
  --mark-surface: #c98a2b;
  --mark-roots:   #57a85e;
  --mark-subsoil: #8a6340;

  /* The subsoil color again under its old name, for anything still asking
   * for it. */
  --soil-brown: var(--mark-subsoil);

  /* The bar's height, needed by anything that has to clear it: the sticky
   * offset on an anchored source entry, and the top of the sidenote column. */
  --topbar-h: 3.25rem;
}

/* --- The dark palette ------------------------------------------------------ */

/* Adopted only when `data-theme="dark"` is on the root element, which the boot
 * script in each page's <head> writes before the first paint -- resolving the
 * reader's stored choice, or their system preference when they have not made
 * one. Deliberately NOT duplicated into a `prefers-color-scheme` media query.
 *
 * That costs a reader with JavaScript disabled their dark mode, which sounds
 * worse than it is: every number on these pages is an empty <b data-stat> slot
 * filled from data.json at runtime, and every chart is drawn by script. Without
 * JavaScript this page is prose full of blanks, and the color of the ground
 * under those blanks is not the problem. The media query would buy that reader
 * nothing and cost a second copy of the palette that could silently drift out
 * of step with this one -- and a palette that disagrees with itself is how the
 * light series colors end up on a dark surface, the one combination neither
 * mode is validated for.
 *
 * The hues are re-picked, not dimmed. Every one clears 6.7:1 against this
 * surface, and the three chart series were re-run through the same color-vision
 * separation check as the light set: worst pair 6.4 dE simulated, against 6.8
 * for the light palette under the identical procedure. The dark set is a hair
 * tighter and comfortably inside the same margin.
 */
:root[data-theme="dark"] {
  color-scheme: dark;

  /* The same green cast as the light mode, taken to the other end. Not a
   * neutral near-black: the light page is warm paper and deep green ink, and
   * a dark mode that goes gray reads as a different site rather than as the
   * same one after dark. Dark enough that the greens and clays sitting on it
   * are the only chroma in view. */
  --surface:        #12150f;
  --surface-raised: #1c201a;
  --border:         #333a2f;
  --text-primary:   #f1f0e8;
  --text-secondary: #b5b9ac;
  --text-muted:     #868a7c;

  --surface-rgb: 18 21 15;

  --tint-strength: 2.2;
  --backdrop-opacity: 0.10;

  /* Re-picked with the light set, and this is the first version of this palette
   * to pass the lightness-band check -- every dark set before it sat above the
   * 0.48-0.67 band and failed, which is recorded here because the failure was
   * carried knowingly for months and it would be easy to reintroduce by
   * brightening these three "so they show up better".
   *
   * This set also clears CVD separation outright -- 9.9 ΔE deutan on the
   * clay-green pair, against the 7.1 WARN the previous dark palette carried.
   * The site still ships the secondary encodings that WARN required (marker
   * shape on the scatters, a categorical axis elsewhere, a table view on every
   * chart) and they stay: they were the right thing to have regardless of
   * whether a check is currently demanding them. */
  --series-1: #5B93D5;
  --series-2: #CE5C36;
  --series-3: #35A886;
  --series-neutral: #8d9186;

  --grid: #262b22;

  /* The light accents are deep by design, and deep on near-black is invisible,
   * so these are the same hues lifted rather than the same values reused. */
  --accent-green:   #8FBE72;
  --accent-slate:   #A8B79E;
  --accent-blue:    #7FB6C9;
  --accent-amber:   #D9A441;
  --accent-red:     #E88A66;
  --accent-plum:    #D286A0;
  --accent-violet:  #A896D8;
  --accent-magenta: #E1789C;
  --accent-orange:  var(--accent-red);

  --accent: var(--accent-green);
  --accent-on-dark: #8FBE72;

  /* Deeper, not lighter. See the note on --shadow-soft above. */
  --shadow-soft: 0 4px 18px rgb(0 0 0 / 0.5);
  --shadow-lift: 0 18px 50px rgb(0 0 0 / 0.62);
  --scrim: rgb(0 0 0 / 0.62);
}

:root {
  /* Prose width. A line wants roughly 65-85 characters whatever the monitor, so
   * the column is set in rem and the *root font size* grows with the viewport
   * instead -- the same sentence then fills more of a wide screen at a size that
   * suits the viewing distance, rather than becoming an unreadable long line.
   * On a 3440px ultrawide a fixed 34rem column renders as a ribbon down the
   * middle, which is what this replaces. */
  --measure: min(46rem, 92vw);

  /* There is deliberately no second, wider figure track. Charts and reference
   * tables used to break out past the prose on the argument that a drawing has
   * no line length to protect -- but the result was every figure on the page
   * hanging past the text on both sides, which reads as a layout fault rather
   * than as emphasis. Figures share the prose column: one left edge and one
   * right edge down the whole page. Anything genuinely too wide to fit (primer
   * sequences, the chart tables) scrolls inside its own box rather than pushing
   * the page out. */
}

/* Grows with the viewport but tops out at 18px. The first attempt capped at
 * 22px, which on a 3440px monitor made the body copy read like large-print --
 * the column filled the space, but at a size nobody wants to read prose in. */
html {
  font-size: clamp(15.5px, 0.25vw + 14px, 18px);
  /* The top bar is sticky, so an anchor jump would otherwise land with the
   * heading tucked underneath it. */
  scroll-padding-top: 4.75rem;
}

/* Two accents, not eight.
 *
 * Every section used to carry its own hue -- slate, blue, green, plum, amber,
 * red, violet, magenta -- on the argument that color should mark where you are
 * in the argument. It does not work, for a reason that has nothing to do with
 * which hues were chosen: a reader cannot hold eight color meanings at once, so
 * eight accents down one page do not say "you are in section six", they say
 * "this site has a palette". Nothing else published looks like that, and it was
 * the loudest single thing about these pages.
 *
 * So green is the site's color and every section wears it, except where the
 * page turns on its own claim. The clay is the one warm hue deep enough to read
 * as a caution without shouting, and it now means exactly one thing wherever it
 * appears: this is where the study argues against itself. Both pages agree on
 * it, which is the whole benefit of spending a second color on one idea rather
 * than a different color on each heading.
 *
 * This costs the section map its eleven colors and the progress line along the
 * bar its changing hue. That was the argument for keeping the rotation, and it
 * was backwards: a map of eleven identical dots with one in a different color
 * is a map you can read at a glance, and eleven colored dots is a decoration
 * that happens to be shaped like a map. */
#limits { --accent: var(--accent-red); }

*, *::before, *::after { box-sizing: border-box; }

