/* Vendored from skill-tufte-viz @ cebcf16 by scripts/sync-tufte.sh — do not edit. */

/* ───────────────────────────────────────────────────────────────────────────
   Tufte Viz · Color tokens
   The page is the canvas. Warm paper, warm ink, hairline rules — and exactly
   ONE accent, crimson, spent at the single moment that deserves the eye.

   Two layers:
   1. --tufte-*  base tokens the chart recipes read directly (do not rename).
   2. Semantic aliases (--text-*, --surface-*, --border-*) for UI chrome.

   Light and midnight paper are one declaration each: every colour is a
   light-dark(light, dark) pair, resolved by the element's `color-scheme`.
     default                → light paper
     class="tufte-dark"     → midnight paper (on :root or any wrapper)
     class="tufte-auto"     → follows the system preference
     class="tufte-light"    → forces light inside an auto/dark ancestor
   Import this file unchanged; never fork it to switch the dark trigger.
   ─────────────────────────────────────────────────────────────────────────── */

:root { color-scheme: light; }
.tufte-dark  { color-scheme: dark; }
.tufte-auto  { color-scheme: light dark; }
.tufte-light { color-scheme: light; }

:root {
  /* ── Paper — warm off-white surfaces ─────────────────────────────────── */
  --paper:        light-dark(#fbf9f4, #14130f);  /* the page itself          */
  --paper-sunk:   light-dark(#f4f1e9, #1d1b16);  /* recessed wells, zebra    */
  --paper-raised: light-dark(#ffffff, #1d1b16);  /* popovers on paper        */

  /* ── Ink — the data and the words that name it ───────────────────────── */
  --tufte-ink:    light-dark(#111111, #ececec);  /* data, headings, values   */
  --tufte-muted:  light-dark(#8a8a8a, #8f8f8f);  /* ticks, range-frames, rugs */
  --tufte-faint:  light-dark(#d8d8d4, #333130);  /* quietest mark (gridrule) */
  --ink-soft:     light-dark(#4a473f, #cfcabe);  /* body prose on paper      */
  --ink-quiet:    light-dark(#6b675d, #9b968a);  /* captions, metadata       */

  /* ── Rules — hairline separators, warmer than the ink greys ──────────── */
  --rule:         light-dark(#e7e2d8, #322f29);  /* default 1px divider      */
  --rule-strong:  light-dark(#d6cfc0, #43403a);  /* a divider to be felt     */

  /* ── The one accent. Spend it once per view. ─────────────────────────── */
  --tufte-accent: light-dark(#c1351d, #ff6b4a);  /* the highlighted point    */
  --accent-ink:   light-dark(#9a2a17, #ff8a6e);  /* accent text (AA)         */
  --accent-wash:  light-dark(#f3ddd6, #2a1a14);  /* faintest crimson tint    */

  /* ── Highlighter — a pen stroke over words (selection, found text) ──── */
  --highlight:    light-dark(#fbe7a1, #5a4a1e);

  /* ── Surface — charts paint no background of their own ───────────────── */
  --tufte-bg:     transparent;

  /* ── Semantic aliases — reference these in UI, not the raw values ────── */
  --text-strong:      var(--tufte-ink);
  --text-body:        var(--ink-soft);
  --text-muted:       var(--ink-quiet);
  --text-faint:       var(--tufte-muted);
  --text-accent:      var(--accent-ink);
  --text-on-accent:   light-dark(#fbf9f4, #14130f);

  --surface-page:     var(--paper);
  --surface-sunk:     var(--paper-sunk);
  --surface-card:     var(--paper-raised);
  --surface-accent:   var(--tufte-accent);

  --border-rule:      var(--rule);
  --border-strong:    var(--rule-strong);
  --border-accent:    var(--tufte-accent);

  /* Status — used sparingly; the brand resists semantic color. Greys do
     most of the work; these exist only where a true judgement is encoded. */
  --signal-up:    light-dark(#2f6b3d, #6cae7e);  /* gain (muted forest)      */
  --signal-down:  var(--accent-ink);             /* loss: the crimson family */
}

/* ───────────────────────────────────────────────────────────────────────────
   Tufte Viz · Typography tokens
   A quiet book serif for everything that is read; a system sans only for the
   tiny over-line labels; tabular monospace for every number. Numbers ARE the
   labels — so the figure stack must align in columns.

   ET Book is the lead face — the canonical Tufte-CSS book serif, bundled as a
   web font under tokens/fonts.css (four weights/slants, so nothing is
   synthesised). Charter and Palatino → Georgia follow as graceful fallbacks if
   the web font ever fails to load. Tabular monospace sets every number.
   ─────────────────────────────────────────────────────────────────────────── */

:root {
  /* ── Families ─────────────────────────────────────────────────────────── */
  --font-serif:  "ET Book", Charter, "Charter BT", "Iowan Old Style",
                 "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif;
  --font-sans:   ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
                 Helvetica, Arial, sans-serif;
  --font-mono:   "SFMono-Regular", ui-monospace, "SF Mono", Menlo, Consolas,
                 "Liberation Mono", monospace;

  /* The chart recipes read these three. --tufte-font inherits the host page. */
  --tufte-font:  var(--font-serif);
  --tufte-num:   var(--font-mono);

  /* ── Type scale — modest, print-derived. rem-based, 1rem = 16px ───────── */
  --text-xs:     0.6875rem;  /* 11px — over-line labels, ticks               */
  --text-sm:     0.8125rem;  /* 13px — captions, figcaption, metadata        */
  --text-base:   1rem;       /* 16px — UI body                               */
  --text-md:     1.125rem;   /* 18px — reading body (the gallery default)    */
  --text-lg:     1.3125rem;  /* 21px — figure titles, lead-ins               */
  --text-xl:     1.625rem;   /* 26px — section heads                         */
  --text-2xl:    2.125rem;   /* 34px — page titles                          */
  --text-3xl:    2.75rem;    /* 44px — hero display                         */

  /* Chart-internal label sizes (recipes read --tufte-size*). */
  --tufte-size:     12px;
  --tufte-size-sm:  10px;

  /* ── Weights — the serif is used at 400 / 600 only ────────────────────── */
  --weight-regular: 400;
  --weight-medium:  500;
  --weight-semibold:600;

  /* ── Line heights ────────────────────────────────────────────────────── */
  --leading-tight: 1.08;   /* display headings                              */
  --leading-snug:  1.3;    /* figure titles, short heads                    */
  --leading-body:  1.55;   /* running prose                                 */

  /* ── Letter-spacing ──────────────────────────────────────────────────── */
  --tracking-tight: -0.02em; /* large display                               */
  --tracking-label:  0.08em; /* the uppercase over-line label only          */

  /* ── Stroke weights for chart marks (recipes read these) ──────────────── */
  --tufte-stroke-data: 1.5px;
  --tufte-stroke-axis: 1px;
  --tufte-stroke-rule: 0.5px;
}

/* ───────────────────────────────────────────────────────────────────────────
   Tufte Viz · Spacing, radius, shadow
   Generous margins, tight data. White space is structural — it does the
   separating that borders and boxes would otherwise do. Corners are nearly
   square; the page lies flat, so shadows are a whisper, not a lift.
   ─────────────────────────────────────────────────────────────────────────── */

:root {
  /* ── Spacing scale — 4px base, used for UI gaps & padding ─────────────── */
  --space-1:  0.25rem;   /*  4px */
  --space-2:  0.5rem;    /*  8px */
  --space-3:  0.75rem;   /* 12px */
  --space-4:  1rem;      /* 16px */
  --space-5:  1.5rem;    /* 24px */
  --space-6:  2rem;      /* 32px */
  --space-7:  3rem;      /* 48px */
  --space-8:  4rem;      /* 64px */
  --space-9:  5.5rem;    /* 88px — section rhythm in the gallery            */

  /* Reading measure — prose should never run wider than this. */
  --measure:        38em;
  --measure-narrow: 30em;
  --measure-wide:   52em;

  /* ── Radius — flat paper, square-ish corners ─────────────────────────── */
  --radius-none: 0;
  --radius-sm:   2px;   /* inputs, chips, code spans                        */
  --radius-md:   4px;   /* cards, buttons                                   */
  --radius-lg:   6px;   /* dialogs, larger panels                          */
  --radius-pill: 999px; /* the rare toggle / avatar                        */

  /* ── Borders — hairlines do almost all the work ──────────────────────── */
  --border-hair: 1px solid var(--rule);
  --border-felt: 1px solid var(--rule-strong);
  --border-data: 1.5px solid var(--tufte-ink);

  /* ── Shadow — paper barely lifts. No coloured or blurry drop shadows. ── */
  --shadow-none:  none;
  --shadow-card:  0 1px 0 rgba(40, 36, 28, 0.04);          /* hairline seat */
  --shadow-raise: 0 1px 2px rgba(40, 36, 28, 0.06),
                  0 2px 8px rgba(40, 36, 28, 0.06);         /* popover/dialog*/

  /* ── Motion — fast, near-linear, no bounce. Ink doesn't spring. ──────── */
  --ease-standard: cubic-bezier(0.2, 0, 0, 1); /* @kind other */
  --dur-fast:   90ms;  /* @kind other */
  --dur-base:   160ms; /* @kind other */
}

/* ───────────────────────────────────────────────────────────────────────────
   Tufte Viz · Paper — the tactile layer
   The page becomes a sheet of paper lying on a desk. Opt in with
   class="tufte-tactile" on <html> or <body> (or any ancestor). Without it
   every token here resolves to flat and nothing moves.

   What makes paper read as paper is mostly what is absent: no glow, no gloss,
   no float, no halo round the letters. So the layer is subtractive:
     - the sheet LIES on the desk: a contact shadow, not a lift;
     - uncoated paper is matte: no sheen;
     - paper texture is soft cloudy formation plus a fine tooth, at the edge
       of perception, blended so it neither darkens nor greys the paper;
     - ink sits ON the paper: no letterpress text-shadow, on anything;
     - ink is dense: body text near-black, not screen grey;
     - the sheet carries content; controls live on the desk around it.
   Data-ink never gets grain, shadow or press.

   Midnight follows colors.css: every value is a light-dark() pair, resolved
   by `color-scheme` (.tufte-dark / .tufte-auto). At night the sheet is still
   the lightest thing on the desk — paper in a dark room, not black paper.
   ─────────────────────────────────────────────────────────────────────────── */

:root {
  /* ── Desk — the surface the paper lies on ────────────────────────────── */
  --desk:              light-dark(#5f574c, #121110);
  --desk-edge:         light-dark(#4f483e, #0b0a09);  /* a bar cut into the desk */
  --text-on-desk:      light-dark(#f3efe6, #ddd6c8);
  --desk-text-body:    light-dark(#e8e1d4, #c9c2b4);  /* the aliases .tufte-desk re-maps */
  --desk-text-muted:   light-dark(#d9d1c2, #a39c8e);  /* ≥ 4.5:1 on the desk */
  --desk-text-faint:   light-dark(#b3aa99, #6f695e);  /* decoration only */
  --desk-text-accent:  light-dark(#ffc2b3, #ff8a6e);  /* crimson is unreadable on the desk */
  --desk-rule:         light-dark(rgba(0,0,0,.22), rgba(255,255,255,.08));
  --desk-rule-strong:  light-dark(rgba(0,0,0,.34), rgba(255,255,255,.14));

  /* ── Grain — two SVG noise tiles, blended soft-light so the average colour
        of the surface is unchanged. Formation: low-frequency clouds (the
        fibre density of real sheets). Tooth: the fine surface. Frequencies
        are whole multiples of the tile so the tiles stitch without seams. ─ */
  --grain-formation: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='480'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0125' numOctaves='4' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='480' height='480' filter='url(%23n)' opacity='.32'/%3E%3C/svg%3E"); /* @kind other */
  --grain-formation-faint: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='480' height='480'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0125' numOctaves='4' seed='11' stitchTiles='stitch'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='480' height='480' filter='url(%23n)' opacity='.14'/%3E%3C/svg%3E"); /* @kind other */
  --grain-tooth:     url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' seed='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)' opacity='.3'/%3E%3C/svg%3E"); /* @kind other */
  --grain-paper: var(--grain-tooth), var(--grain-formation); /* @kind other */
  --grain-desk:  var(--grain-tooth), var(--grain-formation-faint); /* @kind other */
  /* Soft-light bites harder on dark surfaces; midnight halves it. */
  --grain-strength: 1;
  --grain-stamp: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence baseFrequency='.8' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 -1.4'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E"); /* @kind other */
  --sheen-paper: none; /* @kind other — uncoated paper is matte */

  /* ── Shadows — a sheet lying flat: its edge, and a short contact shadow ─ */
  --shadow-sheet: 0 0 0 .5px light-dark(rgba(30,22,12,.18), rgba(0,0,0,.7)),
                  0 1px 1px light-dark(rgba(30,22,12,.20), rgba(0,0,0,.55)),
                  0 2px 6px -2px light-dark(rgba(30,22,12,.30), rgba(0,0,0,.6));
  --shadow-sheet-under: 0 1px 3px light-dark(rgba(30,22,12,.25), rgba(0,0,0,.6));
  --shadow-paper: 0 0 0 .5px light-dark(rgba(40,36,28,.14), rgba(0,0,0,.5)),
                  0 1px 2px light-dark(rgba(40,36,28,.14), rgba(0,0,0,.5));   /* a small sheet on a sheet */

  /* ── Rules — printed, one hairline of ink ────────────────────────────── */
  --rule-deboss: linear-gradient(var(--rule-strong), var(--rule-strong)); /* @kind other */
  --rule-emboss: linear-gradient(var(--desk-rule), var(--desk-rule));     /* @kind other */

  /* ── Controls — a well for text entry, a nudge for a pressed button ──── */
  --press-shallow: inset 0 1px 2px light-dark(rgba(40,36,28,.16), rgba(0,0,0,.6)); /* @kind shadow */
  --press-deep:    inset 0 2px 3px light-dark(rgba(0,0,0,.45), rgba(0,0,0,.9));    /* @kind shadow */
  --accent-stamp:  var(--tufte-accent);

  /* Type is never pressed. These slots stay for older consumers. */
  --text-press-paper: none;
  --text-press-desk:  none;

  /* ── Live slots — components read THESE. Flat until .tufte-tactile. ──── */
  --text-press:     none;                 /* @kind other */
  --press-primary:  none;                 /* @kind other */
  --press-secondary:none;                 /* @kind other */
  --surface-button: var(--paper-raised);
}

.tufte-dark { --grain-strength: .5; }
@media (prefers-color-scheme: dark) {
  .tufte-auto:not(.tufte-light) { --grain-strength: .5; }
}

.tufte-tactile {
  /* Paper stock: warm, matte, a touch below screen white. */
  --paper:          light-dark(#f6f1e6, #1f1c18);
  --paper-sunk:     light-dark(#ede7da, #191713);
  --paper-raised:   light-dark(#fbf8f1, #25221d);
  --surface-button: light-dark(#f1ebde, #25221d);
  /* Ink on it: dense and warm. */
  --tufte-ink:      light-dark(#161310, #ece6da);
  --ink-soft:       light-dark(#2b2824, #d3ccbe);  /* body — 13:1 on the sheet */
  --ink-quiet:      light-dark(#5a554b, #a39c8e);
  --tufte-muted:    light-dark(#8c8579, #7d766a);
  --rule:           light-dark(#e3dccd, #34302a);
  --rule-strong:    light-dark(#cfc6b3, #48433b);
  --shadow-card:    var(--shadow-paper);
  --shadow-raise:   var(--shadow-sheet-under);
  --press-primary:  var(--press-deep);
  --press-secondary:var(--press-shallow);
  --surface-page:   var(--paper);
  --surface-sunk:   var(--paper-sunk);
  --surface-card:   var(--paper-raised);
}

/* ── Surfaces ──────────────────────────────────────────────────────────── */

/* The desk. Put it on <body> (or a full-height wrapper). */
.tufte-desk {
  background: var(--desk);
  position: relative;
  isolation: isolate;
  min-height: 100vh;
  color: var(--text-on-desk);
  /* Everything not on a sheet reads in desk ink: the semantic aliases are
     re-mapped here and restored by every paper surface (.tufte-sheet below).
     Chrome that paints its own paper must restore them the same way. */
  --text-strong:   var(--text-on-desk);
  --text-body:     var(--desk-text-body);
  --text-muted:    var(--desk-text-muted);
  --text-faint:    var(--desk-text-faint);
  --text-accent:   var(--desk-text-accent);
  --border-rule:   var(--desk-rule);
  --border-strong: var(--desk-rule-strong);
}
.tufte-tactile .tufte-desk::before, .tufte-tactile.tufte-desk::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: var(--grain-desk); mix-blend-mode: soft-light; opacity: var(--grain-strength);
}

/* A sheet of paper. */
.tufte-sheet {
  background: var(--paper);
  color: var(--text-body);
  border-radius: var(--radius-none, 0);
  position: relative;
  isolation: isolate;
  /* Paper ink, restored — a sheet on the desk reads like a page again. */
  --text-strong:   var(--tufte-ink);
  --text-body:     var(--ink-soft);
  --text-muted:    var(--ink-quiet);
  --text-faint:    var(--tufte-muted);
  --text-accent:   var(--accent-ink);
  --border-rule:   var(--rule);
  --border-strong: var(--rule-strong);
}
.tufte-tactile .tufte-sheet, .tufte-tactile.tufte-sheet { box-shadow: var(--shadow-sheet); }
.tufte-tactile .tufte-sheet::before, .tufte-tactile.tufte-sheet::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: var(--grain-paper); mix-blend-mode: soft-light; opacity: var(--grain-strength);
}

/* Card component (and anything with .tufte-card): grain under tactile. */
.tufte-tactile .tufte-card::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  border-radius: inherit; background: var(--grain-paper); mix-blend-mode: soft-light;
}

/* Wrap a sheet in this to get a second sheet peeking out behind it. */
.tufte-sheet-stack { position: relative; }
.tufte-tactile .tufte-sheet-stack::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--paper-sunk);
  box-shadow: var(--shadow-sheet-under);
  transform: rotate(-1.2deg) translate(7px, 5px);
}

/* ── Rules — one printed hairline ─────────────────────────────────────── */
.tufte-rule        { height: 1px; border: 0; margin: 0; background: var(--rule); }
.tufte-tactile .tufte-rule          { background: var(--rule-strong); }
.tufte-tactile .tufte-rule--desk    { background: var(--desk-rule); }

/* ── Stamp — the accent as red ink stamped once per page ─────────────── */
.tufte-stamp {
  display: inline-grid; place-items: center;
  width: 5.2em; height: 5.2em; padding: .4em; box-sizing: border-box;
  border: 2px solid var(--accent-stamp); border-radius: 50%;
  color: var(--accent-stamp);
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; text-align: center; line-height: 1.25;
  transform: rotate(-12deg); opacity: .6;
  -webkit-mask: var(--grain-stamp); mask: var(--grain-stamp);
}

/* Reduce the show for people who ask for it. */
@media (prefers-reduced-transparency: reduce) {
  .tufte-desk::before, .tufte-sheet::before { display: none; }
}

/* ───────────────────────────────────────────────────────────────────────────
   Tufte Viz · Base affordances
   The minimal shared CSS every chart figure relies on. Charts still render
   without it, but this gives figures their type, color inheritance, and the
   inline-sparkline alignment. Keep this lean — the page is the canvas.
   ─────────────────────────────────────────────────────────────────────────── */

.tufte-figure {
  font-family: var(--tufte-font);
  color: var(--tufte-ink);
  background: var(--tufte-bg);
  margin: 0;
}
.tufte-figure svg { display: block; overflow: visible; }
.tufte-figure text { font-family: var(--tufte-font); fill: var(--tufte-ink); }
.tufte-figure .tufte-value {
  font-family: var(--tufte-num);
  font-variant-numeric: tabular-nums;
}
.tufte-figure figcaption {
  font-family: var(--tufte-font);
  font-size: var(--tufte-size-sm);
  color: var(--tufte-muted);
  margin-top: 0.4em;
  max-width: 30em;
  line-height: 1.4;
}

/* Sparklines sit inline in running text at the x-height of their line. */
.tufte-sparkline {
  display: inline-block;
  vertical-align: -0.15em;
  line-height: 1;
}

/* A chart needs a width-constrained parent or its viewBox SVG collapses.
   This helper guarantees the SVG fills whatever box you give .tufte-chart. */
.tufte-chart { width: 100%; }
.tufte-chart svg { width: 100%; height: auto; display: block; }
