/* ---- the site's own pages: home, writing, articles, about, contact ----
   Colours are base.css tokens and the brand face comes from site.css, so these
   pages and the dashboards read as one system. */

h2 {
  font-family: var(--sc-display); font-weight: 800; font-size: 30px;
  line-height: 1.05; letter-spacing: .005em; margin: 0 0 12px;
}
.more { margin: 14px 0 0; font-size: 13px; }
.more a, .prose a, .lede a, .empty a {
  color: var(--ink); text-decoration: underline; text-decoration-color: var(--rule);
  text-underline-offset: 3px;
}
.more a::after { content: "\00a0\2192"; }
.more a:hover, .prose a:hover { text-decoration-color: currentColor; }
.empty { color: var(--ink-2); font-size: 14px; margin: 0; }

/* buttons: ink on plane, the strongest contrast the palette has */
.cta { display: flex; flex-wrap: wrap; gap: 10px; margin: 20px 0 0; }
.btn {
  display: inline-block; padding: 9px 16px; border-radius: 7px;
  font: 600 14px/1.2 var(--sc-text); text-decoration: none; cursor: pointer;
  color: var(--ink); background: transparent; border: 1px solid var(--rule);
}
.btn:hover { border-color: var(--ink-2); }
.btn-primary { color: var(--plane); background: var(--ink); border-color: var(--ink); }
.btn-primary:hover { background: var(--ink-2); border-color: var(--ink-2); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---- home ----
   The logo lives in the bar now, so the mission is the first thing under it
   and its heading is the page's h1. It runs most of the way across rather
   than sitting in a 64ch column on the left, which left the top of the page
   narrow above cards that span the whole of it. */
.home-mission { max-width: 88ch; margin: 0 0 40px; }
.mission-head {
  margin: 0 0 14px; font-family: var(--sc-display); font-weight: 800;
  font-size: clamp(28px, 3.6vw, 44px); line-height: 1.05; letter-spacing: .005em;
  color: var(--ink); text-wrap: balance;
}
.mission-head .hum { color: var(--sc-hum); }
.mission-body { margin: 0; font-size: 16px; line-height: 1.6; color: var(--ink-2); }

.feature {
  display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 0;
  background: var(--surface); border: 1px solid var(--ring); border-radius: 12px;
  overflow: hidden; margin: 0 0 40px;
}
.feature-pic { display: block; line-height: 0; background: var(--row-hover); }
.feature-pic .thumb { margin: 0; border: 0; border-radius: 0; height: 100%; }
.feature-pic .thumb-svg { height: 100%; min-height: 260px; }
.feature-body { padding: 26px 28px 24px; }

.dash-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--grid); }
.dash-list a {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 10px 0; border-bottom: 1px solid var(--grid); text-decoration: none; color: var(--ink);
}
.dash-list a:hover .dl-title { text-decoration: underline; text-underline-offset: 3px; }
.dl-title { font-family: var(--sc-display); font-weight: 700; font-size: 20px; }
.dl-meta { font-size: 11px; letter-spacing: .03em; text-transform: uppercase; color: var(--ink-2); text-align: right; }
/* On a phone the title and its counts cannot share a line: every name wrapped
   to two lines with the counts ragged beside it. Stacked, each row is a name
   and the numbers under it. */
@media (max-width: 640px) {
  .dash-list a { display: grid; gap: 2px; }
  .dl-meta { text-align: left; }
}

/* a feature whose lead article names no dashboard, so there is no picture */
.feature-bare { grid-template-columns: minmax(0, 1fr); }
.band { margin: 0 0 40px; }
.duo { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.duo-card {
  display: block; padding: 20px 22px; border-radius: 12px; text-decoration: none; color: inherit;
  background: var(--surface); border: 1px solid var(--ring);
  transition: border-color .12s ease;
}
.duo-card:hover { border-color: var(--rule); }
.duo-card h2 { font-size: 24px; margin-bottom: 6px; }
.duo-card p { margin: 0; color: var(--ink-2); font-size: 14px; }

@media (max-width: 760px) {
  .feature, .duo { grid-template-columns: minmax(0, 1fr); }
  .feature-pic .thumb-svg { min-height: 0; }
}

/* ---- writing ---- */
/* The index takes the same measure as the home page's mission rather than the
   full 1240px, where a dek ran nearly a thousand pixels on one line. */
.masthead, .lede, .post-list { max-width: 88ch; }
.lede { color: var(--ink-2); margin: 0 0 22px; }
.post-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--grid); }
.post-item a {
  display: grid; gap: 3px; padding: 16px 0; border-bottom: 1px solid var(--grid);
  text-decoration: none; color: inherit;
}
.post-item a:hover .post-title { text-decoration: underline; text-underline-offset: 3px; }
/* An article that names a dashboard gets its thumbnail beside the text. The
   picture column is fixed so a list of them lines up down the page whatever
   the titles do. */
.post-item.has-pic a { grid-template-columns: 200px minmax(0, 1fr); gap: 20px; align-items: start; }
.post-text { display: grid; gap: 3px; align-content: start; }
.post-pic {
  border-radius: 8px; overflow: hidden; line-height: 0;
  background: var(--row-hover); border: 1px solid var(--ring);
}
.post-pic .thumb { margin: 0; border: 0; border-radius: 0; }
.post-pic .thumb-svg { display: block; width: 100%; height: auto; }
@media (max-width: 640px) {
  .post-item.has-pic a { grid-template-columns: minmax(0, 1fr); gap: 12px; }
}
.post-when { font-size: 12px; color: var(--ink-2); letter-spacing: .02em; }
.post-title { font-family: var(--sc-display); font-weight: 800; font-size: 24px; line-height: 1.1; color: var(--ink); }
.post-dek { font-size: 14px; color: var(--ink-2); }

/* ---- an article, and about ---- */
/* The column is centred in the 1240px page rather than pinned to its left,
   where a 68ch measure left half the screen empty and the article read as a
   narrow strip. 76ch is as wide as it goes: past about 80 characters the eye
   loses the start of the next line. */
.post { max-width: 76ch; margin-inline: auto; }
.post > h1 { font-size: clamp(34px, 5vw, 48px); margin: 6px 0 10px; }
.post > .post-dek { font-size: 18px; line-height: 1.45; margin: 0 0 28px; display: block; }
.prose { font-size: 17px; line-height: 1.7; color: var(--ink); }
.prose p, .prose ul, .prose ol, .prose blockquote { margin: 0 0 1.1em; }
.prose h2 { font-size: 28px; margin: 1.6em 0 .5em; }
.prose h3 { font-family: var(--sc-display); font-weight: 700; font-size: 22px; margin: 1.4em 0 .4em; }
.prose img { display: block; max-width: 100%; height: auto; border-radius: 8px; margin: 1.4em 0; }
.prose blockquote { padding-left: 18px; border-left: 3px solid var(--sc-hum); color: var(--ink-2); }
.prose code { font: 0.9em ui-monospace, SFMono-Regular, Menlo, monospace; background: var(--row-hover); padding: 1px 5px; border-radius: 4px; }
.prose hr { border: 0; border-top: 1px solid var(--grid); margin: 2em 0; }

/* A data table in an article, read the way the dashboards' tables are: shaded
   on the site's diverging ramp so the ends are visible before a number is. The
   table scrolls inside its own box so a wide one never pushes the page
   sideways -- and that box is only ever around a table, because putting the
   overflow on the figure would have clipped the chart's hover panel. */
/* A figure is allowed to be wider than the text it sits in. The reading
   measure is 76ch because prose past about 80 characters is hard to track
   back from, but a table of six columns or a chart of 81 games has no such
   limit -- pinned to the text width the events table overflowed its own box.
   It centres on the column and stops at the page's own 1240px. */
/* Figures sit in a rail beside the prose rather than interrupting it. The
   article is wider than the reading measure so the text column still lands
   near 64 characters, and a chart measures its own box: it is drawn smaller
   in the rail rather than drawn wide and squeezed into it.

   Under 1000px the rail has nowhere to go, so a figure takes the full width
   and the column returns to the reading measure. */
.prose figure { margin: 1.7em 0; }
@media (min-width: 1000px) {
  .post { max-width: 1180px; }
  /* Smaller than the single-column size. The text column is about 470px here
     rather than the 544 it had, and type that was set for the wider measure
     reads loose in it -- the line length and the size have to move together. */
  .post .prose { font-size: 15.5px; line-height: 1.65; }
  .post .prose h2 { font-size: 25px; }
  .post .prose h3 { font-size: 20px; }
  /* The cap is chosen to land on the same width the text wraps to beside a
     figure, so the column is one width from the first line to the last rather
     than stepping wider every time a float ends. */
  .post .prose > p, .post .prose > h2, .post .prose > h3, .explore {
    max-width: 51ch;
  }
  /* The dek and the sources span the article. The dek is a single line under a
     full-width title and belongs to it rather than to the text column; the
     sources are checked rather than read through, so a long line costs nothing
     and the block ends up short. */
  .post > .post-dek { font-size: 20px; max-width: none; }
  .notes { max-width: none; }
  .post .prose > figure {
    float: right; clear: right; width: 54%;
    margin: .2em 0 1.8em 44px;
  }
  .post .prose > figure figure { width: auto; margin: 0; }
  .notes, .explore { clear: both; }
}
.prose .table-scroll { overflow-x: auto; }
.prose table { width: 100%; border-collapse: collapse; font-size: 14px; font-variant-numeric: tabular-nums; }
.prose thead th {
  font: 600 11.5px/1.3 var(--sc-text); text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-2); padding: 0 12px 9px; border-bottom: 1px solid var(--rule); white-space: nowrap;
}
.prose tbody td { padding: 9px 12px; border-bottom: 1px solid var(--grid); white-space: nowrap; }
.prose tbody tr:last-child td { border-bottom: 0; }
/* the label column reads as text, the measured columns as numbers */
.prose thead th:first-child, .prose tbody td:first-child { text-align: left; }
.prose thead th:not(:first-child), .prose tbody td:not(:first-child) { text-align: right; }
/* A table whose cells carry sentences rather than figures. Every table on the
   site until now held numbers, where nowrap and a right edge line the digits
   up; a column reading "Adds unlike denominators, weights them equally and
   ignores park and era" needs to wrap and to start at the left, or it pushes
   the table wider than the page and reads backwards. Written as a modifier so
   the numeric default stays the default. */
.prose figure[data-prose] table { font-variant-numeric: normal; }
.prose figure[data-prose] tbody td, .prose figure[data-prose] thead th {
  white-space: normal; text-align: left; vertical-align: top;
}
.prose figure[data-prose] tbody td:first-child { font-weight: 600; color: var(--ink); }
.prose td.p0{background:var(--b0);color:var(--i0)}   .prose td.p1{background:var(--b1);color:var(--i1)}
.prose td.p2{background:var(--b2);color:var(--i2)}   .prose td.p3{background:var(--b3);color:var(--i3)}
.prose td.p4{background:var(--b4);color:var(--i4)}   .prose td.p5{background:var(--b5);color:var(--i5)}
.prose td.p6{background:var(--b6);color:var(--i6)}   .prose td.p7{background:var(--b7);color:var(--i7)}
.prose td.p8{background:var(--b8);color:var(--i8)}   .prose td.p9{background:var(--b9);color:var(--i9)}
.prose td.p10{background:var(--b10);color:var(--i10)}

/* the home-gate line under the events table: the shape of a season, small,
   because the table above it has already given the numbers */
.gt { margin: 0; }
.gt-svg { display: block; width: 100%; height: auto; }
/* 1,049 games in 920px: thin, so the sawtooth reads instead of blurring */
/* the raw gates: texture under the band, not the reading */
.gt-line { fill: none; stroke: var(--ink); stroke-width: .8; opacity: .22; stroke-linejoin: round; }
/* the 40th to 60th percentile as the season goes on */
.gt-band { fill: var(--ink); stroke: none; opacity: .85; }
.gt-band-control { fill: var(--sc-hum); opacity: .8; }
/* the park drawn for comparison, in the site's red */
.gt-control { stroke: var(--sc-hum); opacity: .22; }
/* a season played under capacity limits: drawn, and set back from the rest */
.gt-dim { opacity: .3; }
.gt-key { font: 12px var(--sc-text); fill: var(--ink-2); }
.gt-k-subject { fill: var(--ink); font-size: 20px; }
.gt-k-control { fill: var(--sc-hum); font-size: 20px; }

/* who is visiting: one dot an opponent, one strip a park */
.op { margin: 0; }
.op-svg { display: block; width: 100%; height: auto; }
.op-grid { stroke: var(--grid); stroke-width: 1; }
.op-rule { stroke: var(--rule); stroke-width: 1; }
.op-dot { stroke: var(--plane); stroke-width: 1.5; }
.op-dot.op-subject { fill: var(--ink); }
.op-dot.op-control { fill: var(--sc-hum); }
.op-park { font: 700 15px var(--sc-display); }
.op-park.op-subject { fill: var(--ink); }
.op-park.op-control { fill: var(--sc-hum); }
.op-end { fill: var(--ink-2); font: 600 11px var(--sc-text); letter-spacing: .03em; }
.op-tick, .op-axis {
  fill: var(--ink-muted); font: 11px var(--sc-text); letter-spacing: .04em;
  text-transform: uppercase;
}
@media (max-width: 640px) {
  .op-park { font-size: 22px; }
  .op-end { font-size: 17px; }
  .op-tick, .op-axis { font-size: 17px; }
  .op-dot { r: 8; }
}
.gt-cap { fill: none; stroke: var(--rule); stroke-width: 1; stroke-dasharray: 4 5; }
.gt-year { stroke: var(--grid); stroke-width: 1; }
.gt-caplabel, .gt-tick {
  fill: var(--ink-muted); font: 11px var(--sc-text); letter-spacing: .04em;
  text-transform: uppercase;
}
/* the two named gates. Ink with a cut-out ring, not red: red is Fenway
   here, and a red dot on the Marlins' band read as the wrong park. */
.gt-dot { fill: var(--plane); stroke: var(--ink); stroke-width: 2.5; }
.gt-note { fill: var(--ink); font: 700 13px var(--sc-display); }
@media (max-width: 640px) {
  .gt-caplabel, .gt-tick { font-size: 17px; }
  .gt-note { font-size: 20px; }
  .gt-line { stroke-width: 1.6; }
}

/* Two parks' Elbow Room on one axis. The bands are the middle half of the
   games around a date, drawn transparent so an overlap would show -- these two
   never have one, which is the point of putting them on the same axis. */
.ov { margin: 0; }
.ov-svg { display: block; width: 100%; height: auto; }
.ov-grid { stroke: var(--grid); stroke-width: 1; }
.ov-year { stroke: var(--grid); stroke-width: 1; opacity: .5; }
/* the seasons either side of this rule are next to each other on the axis and
   are not next to each other in time: 2020 and 2021 are out */
.ov-year.ov-break { stroke: var(--rule); stroke-width: 1; opacity: 1; stroke-dasharray: 3 4; }
.ov-band { stroke: none; fill-opacity: .3; }
.ov-band.ov-subject { fill: var(--ink); }
.ov-band.ov-control { fill: var(--sc-hum); }
.ov-mid { fill: none; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.ov-mid.ov-subject { stroke: var(--ink); }
.ov-mid.ov-control { stroke: var(--sc-hum); }
/* Both names in ink, for the reason the debut chart's are: the brand red is
   3.95:1 on the light ground, which a band can be and 13px bold type cannot.
   Each name sits at the end of its own band, so the colour is already there. */
.ov-name { fill: var(--ink); font: 700 13px var(--sc-display); paint-order: stroke;
           stroke: var(--plane); stroke-width: 3px; stroke-linejoin: round; }
.ov-tick {
  fill: var(--ink-muted); font: 11px var(--sc-text); letter-spacing: .04em;
}
@media (max-width: 640px) {
  .ov-name { font-size: 16px; }
  .ov-tick { font-size: 14px; }
}

/* A break between groups of rows in an article table: space, no rule and no
   border, so the two halves read as two lists rather than one list with a
   hole in it. */
.prose tr.tr-gap td { padding: 0; height: 9px; border: 0; }

/* A slash line as it accumulated. Three lines on one axis, named where they
   finish rather than in a key, so the eye never leaves the chart. */
.bz { margin: 0; }
.bz-svg { display: block; width: 100%; height: auto; }
.bz-grid { stroke: var(--grid); stroke-width: 1; }
.bz-line { fill: none; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
/* The site's own red and blue, with a neutral for the plainest measure. The
   Finder's outcome wheel was the first try and its gold came to 3.3:1 in light
   -- fine for a stroke, and the weakest thing on a card that has only three
   marks on it. These clear 3.95:1 at worst and every one of them passes the
   bar for type, which is what lets the labels below take their line's colour.

   The order reads as a hierarchy: slugging is the loud one, on-base the
   measured one, average the baseline. */
.bz-avg { stroke: var(--ink-muted); }
.bz-obp { stroke: var(--accent); }
.bz-slg { stroke: var(--sc-hum); }
/* average and on-base run close together for most of the season; the dash
   keeps them apart where the colours alone would not */
.bz-avg.bz-line { stroke-dasharray: 6 4; }
/* The names are ink. Blue and the neutral would carry their line's colour at
   this size, but the brand red measures 3.95:1 on the light ground -- past the
   3:1 a stroke needs and short of the 4.5:1 that 12px bold type needs, and the
   ramp holds no darker red because it is a fill palette. Colouring two of three
   would read as a mistake, so all three take ink and the line running up to
   each label is the key. The halo keeps a name legible where a line crosses
   under it. */
.bz-name { fill: var(--ink); font: 700 12px var(--sc-display); paint-order: stroke;
           stroke: var(--plane); stroke-width: 3px; stroke-linejoin: round; }
.bz-tick, .bz-axis {
  fill: var(--ink-muted); font: 11px var(--sc-text); letter-spacing: .04em;
}
.bz-axis { text-transform: uppercase; }
@media (max-width: 640px) {
  .bz-name { font-size: 14px; }
  .bz-tick, .bz-axis { font-size: 13px; }
}

/* Sources. The superscript is a link, so it needs a target big enough to hit on
   a phone without opening a gap in the line: the padding is horizontal only and
   the line-height is pinned to zero so the paragraph's leading does not move. */
.prose .fn { font-size: 12px; line-height: 0; vertical-align: super; --fn-hot: #c23c38; }
/* the hover red, dark enough to clear 4.5:1 at 12px on the light page (4.98:1);
   on the dark page the site's own red is already well clear of it */
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .prose .fn { --fn-hot: var(--sc-hum); }
}
:root[data-theme="dark"] .prose .fn { --fn-hot: var(--sc-hum); }
/* The number is ink, not the site's red: at 12px the red lands at 3.95:1 on
   this background, under the 4.5:1 small text needs. The red is kept for the
   hover, where it is a state rather than the only thing carrying the meaning. */
.prose .fn a {
  color: var(--ink); text-decoration: none; font-weight: 700;
  padding: 0 2px; font-variant-numeric: tabular-nums;
}
.prose .fn a:hover, .prose .fn a:focus-visible { color: var(--fn-hot); }
.prose .fn a:hover, .prose .fn a:focus-visible { text-decoration: underline; }
/* the line to the dashboard the article was built on: a sentence, not a card */
/* An article that ends by asking for the work gets a bigger close than one
   that ends by pointing at a dashboard: the whole piece is the argument for
   it, so the last line is the thing a reader acts on rather than a footnote
   under the sources.

   Its own name, because .post-ask was already the home page's button row and these
   rules were landing on it -- the Explore the dashboards button came out in a
   bordered box of its own. */
.post-ask {
  margin: 34px 0 0; padding: 22px 24px; clear: both;
  border: 1px solid var(--ring); border-radius: 10px; background: var(--surface);
  max-width: 51ch;
}
.post-ask p { margin: 0 0 12px; font-size: 18px; line-height: 1.45; color: var(--ink); }
.post-ask a {
  display: inline-block; padding: 10px 18px; border-radius: 8px;
  background: var(--ink); color: var(--plane); text-decoration: none;
  font: 600 16px/1 var(--sc-text);
}
.post-ask a:hover { background: var(--sc-hum); }
.post-ask a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.explore { margin: 30px 0 0; font-size: 17px; }
.explore a { color: var(--ink); text-underline-offset: 3px; text-decoration-thickness: 1px; }
.explore a:hover { color: var(--sc-hum); }
.notes { margin: 40px 0 0; padding-top: 22px; border-top: 1px solid var(--grid); }
.notes h2 {
  font-family: var(--sc-display); font-weight: 800; font-size: 20px;
  letter-spacing: .01em; margin: 0 0 14px;
}
.notes ol { margin: 0; padding-left: 22px; counter-reset: none; }
/* Sources sit well under the prose: they are there to be checked, not read
   through, so they take the smallest size the palette still clears 4.5:1 at. */
.notes li {
  margin: 0 0 12px; font-size: 13px; line-height: 1.5; color: var(--ink-2);
  scroll-margin-top: 80px;      /* room above a source jumped to from the text */
}
/* Across the whole article rather than the text column, a source is a short
   line. Smaller again at that width, because the block is being scanned for a
   name, not read. */
@media (min-width: 1000px) {
  .notes li { font-size: 12px; margin-bottom: 9px; }
}
.notes li:target { background: var(--row-hover); border-radius: 6px; }
.notes .note-src { display: block; margin-top: 2px; }
.notes a { color: var(--ink-2); text-underline-offset: 2px; }
.notes a:hover { color: var(--ink); }
.notes .note-back { margin-left: 6px; text-decoration: none; color: var(--ink-2); }
.notes .note-back:hover { color: var(--ink); }
/* About: the text at reading width, the portrait in the column beside it
   rather than wrapped into the text, which left the page's right side empty */
.about > h1 { font-size: clamp(34px, 5vw, 48px); margin: 6px 0 22px; }
/* On About the dek is the page's opening line, not only its meta description:
   it is where the page says who he is before the prose starts. Full width
   above the grid, the same size as an article's. */
.about > h1:has(+ .post-dek) { margin-bottom: 10px; }
.about > .post-dek { font-size: 18px; line-height: 1.45; max-width: 72ch; margin: 0 0 30px; }
@media (min-width: 1000px) { .about > .post-dek { font-size: 20px; } }
.about-grid {
  display: grid; grid-template-columns: minmax(0, 68ch) minmax(200px, 300px);
  gap: 56px; align-items: start; justify-content: space-between;
}
/* The portrait is 960x1200, so it can be shown at 480 and still land two image
   pixels per screen pixel. It only fits beside a 68ch column once the wrap is
   wide enough to hold 600 + 56 + 480 inside its 24px padding; below that the
   photo would come out wider than the text it sits next to. */
@media (min-width: 1200px) {
  .about-grid { grid-template-columns: minmax(0, 68ch) minmax(220px, 480px); }
}
.about-photo {
  display: block; width: 100%; height: auto; margin-top: 6px;
  border-radius: 12px; border: 1px solid var(--ring);
}

@media (max-width: 820px) {
  .about-grid { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .about-photo { order: -1; width: 220px; margin: 0 0 22px; }
}
.placeholder { padding: 14px 16px; border: 1px dashed var(--ink-muted); border-radius: 8px; color: var(--ink-2); font-size: 15px; }

/* the nudge toward the dashboards at the end of a page */
.nudge {
  display: grid; gap: 4px; margin: 34px 0 10px; padding: 18px 20px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--ring); border-left: 4px solid var(--sc-hum);
  text-decoration: none; color: inherit; transition: border-color .12s ease;
}
.nudge:hover { border-color: var(--rule); border-left-color: var(--sc-hum); }
.nudge-title { font-family: var(--sc-display); font-weight: 800; font-size: 26px; line-height: 1.05; }
.nudge-title::after { content: "\00a0\2192"; }
.nudge-blurb { color: var(--ink-2); font-size: 14px; }

/* ---- contact ---- */
.form { display: grid; gap: 16px; max-width: 620px; margin-top: 8px; }
.form-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.form label { display: grid; gap: 6px; font-size: 13px; font-weight: 600; color: var(--ink-2); }
.form input, .form select, .form textarea {
  font: 15px/1.4 var(--sc-text); color: var(--ink); background: var(--surface);
  border: 1px solid var(--rule); border-radius: 7px; padding: 9px 11px; width: 100%;
}
.form textarea { resize: vertical; }
.form input:focus-visible, .form select:focus-visible, .form textarea:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent;
}
.form p { margin: 0; }
.hp { position: absolute; left: -9999px; }
.form-note {
  padding: 10px 14px; border-radius: 8px; border-left: 3px solid var(--sc-hum);
  background: var(--surface); color: var(--ink); font-size: 14px;
}
@media (max-width: 560px) { .form-row { grid-template-columns: minmax(0, 1fr); } }

/* ---- Elbow Room chart ----
   Colours are the site's eleven-step scale, used here as a single ramp: red
   where a park is packed, blue where it is empty. */
.eb { margin: 0 0 8px; position: relative; }
.eb-svg { display: block; width: 100%; height: auto; }
.eb-grid { stroke: var(--grid); stroke-width: 1; }
.eb-axis { stroke: var(--ink-muted); stroke-width: 1.5; }
.eb-tick { fill: var(--ink-2); font: 12px var(--sc-text); font-variant-numeric: tabular-nums; }
.eb-label { fill: var(--ink-2); font: 600 13px var(--sc-text); }
.eb-note { fill: var(--ink-muted); font: 11px var(--sc-text); letter-spacing: .06em; text-transform: uppercase; }
.eb-year { fill: var(--ink); font: 700 13px var(--sc-display); }
.eb-dot { stroke: var(--surface); stroke-width: 1; cursor: pointer; }
.eb-plain { opacity: .72; }
.eb-trace { stroke: var(--ink); stroke-width: 1.6; }
.eb-on { stroke: var(--ink); stroke-width: 2.4; }
.eb-dot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.eb-path { fill: none; stroke: var(--ink); stroke-width: 2; opacity: .5; stroke-linejoin: round; }
.eb-c0{fill:var(--b10)} .eb-c1{fill:var(--b9)} .eb-c2{fill:var(--b8)} .eb-c3{fill:var(--b7)}
.eb-c4{fill:var(--b6)} .eb-c5{fill:var(--b5)} .eb-c6{fill:var(--b4)} .eb-c7{fill:var(--b3)}
.eb-c8{fill:var(--b2)} .eb-c9{fill:var(--b1)} .eb-c10{fill:var(--b0)}
.eb-cap { font-size: 12.5px; line-height: 1.5; color: var(--ink-2); margin-top: 10px; }
.eb-tip {
  position: absolute; z-index: 2; pointer-events: none; display: grid; gap: 2px;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 8px;
  padding: 8px 11px; font: 13px/1.35 var(--sc-text); color: var(--ink-2);
  box-shadow: 0 2px 10px rgba(0,0,0,.10); white-space: nowrap;
}
/* An author display rule beats the browser's own [hidden] rule, so without
   this the box never hid no matter what the script set. */
.eb-tip[hidden] { display: none; }
.eb-tip b { color: var(--ink); font-family: var(--sc-display); font-size: 17px; font-weight: 800; }
.eb-path1 { stroke-dasharray: 7 5; }

/* option B's controls: the site's highlight/filter pair and a club picker */
.eb-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-bottom: 14px; }
.eb-seg { display: flex; border: 1px solid var(--rule); border-radius: 7px; overflow: hidden; }
.eb-seg button {
  font: 600 13px var(--sc-text); padding: 6px 13px; border: 0; cursor: pointer;
  background: transparent; color: var(--ink-2);
}
.eb-seg button[aria-pressed="true"] { background: var(--ink); color: var(--plane); }
.eb-clubs { display: flex; flex-wrap: wrap; gap: 4px; }
.eb-chip {
  font: 600 11.5px var(--sc-text); letter-spacing: .02em; padding: 4px 7px; cursor: pointer;
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--ring); border-radius: 5px;
}
.eb-chip:hover { border-color: var(--rule); color: var(--ink); }
.eb-chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--plane); }
.eb-clear {
  font: 600 13px var(--sc-text); padding: 6px 12px; cursor: pointer; color: var(--ink-2);
  background: transparent; border: 1px solid var(--rule); border-radius: 7px;
}
.eb-clear:hover { color: var(--ink); }
.eb-dim { opacity: .18; }
.eb-kin { stroke: var(--ink); stroke-width: 1.6; opacity: 1; }
