/* jtrr.org -- the site stylesheet.
 *
 * Extends the palette and typography the /stats rewrite established
 * (PUBLIC-SITE.md sections 2 and 5) to the rest of the public site.
 *
 * NO FRAMEWORK, NO CDN, NO BUILD STEP. One file a person can edit in twenty
 * years, which is the site's greatest operational virtue and the thing the
 * plan says not to trade away.
 *
 * HOW THIS WORKS ON PAGES THAT HAVE NOT BEEN REWRITTEN
 *
 * The legacy pages are laid out in tables and carry presentational markup:
 * 61 <font>, 44 border=2, 36 bgcolor=, 35 <center> across the top-level
 * pages. Rather than rewrite that markup - which risks losing data on pages
 * holding twenty-eight years of results - this stylesheet OVERRIDES it. A CSS
 * declaration always beats a presentational attribute, so `background` beats
 * `bgcolor` and there is nothing to edit. The markup can then be retired page
 * by page at leisure, and the page looks right in the meantime.
 *
 * That is also why the selectors below reach for things like `#newsitem` and
 * `font[color="green"]`: they are the handles the existing HTML gives us. They
 * are not good HTML and are not meant to be permanent.
 */

/* ---------------------------------------------------------------- tokens - */

:root {
  --ink: #1d2530;      /* body text */
  --mut: #6b7684;      /* secondary text */
  --line: #dde3ea;     /* rules and borders */
  --bar: #4a7fb5;      /* the blue: links, chart bars */
  --bar2: #8fb8dd;
  --acc: #c2703d;      /* the rust: accents, hover */
  --soft: #f5f8fb;     /* panel fill */
  --ok: #2f7d4f;       /* yes / positive */
  --no: #97a2ae;       /* no / absent */
  --warn: #9a6b12;
  --page: #ffffff;
  --band: #eef3f8;     /* nav and table-head band */
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e7ecf2; --mut: #9aa7b5; --line: #2b3644; --bar: #78aede; --bar2: #4a7fb5;
    --acc: #e2915c; --soft: #18202b; --ok: #6cc08c; --no: #6b7684; --warn: #d3a44a;
    --page: #111823; --band: #18202b;
  }
}

/* ------------------------------------------------------------------ base - */

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font: 15px/1.55 var(--sans);
}

a { color: var(--bar); text-decoration: none; }
a:hover, a:focus-visible { text-decoration: underline; }

/* Skip past the nav. The results tables are long and a keyboard or screen
   reader user should not have to walk the whole navigation on every page. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 10;
  background: var(--page); color: var(--ink); padding: 9px 14px;
  border: 2px solid var(--bar); border-radius: 0 0 7px 0;
}
.skip:focus { left: 0; }

/* --------------------------------------------------------------- masthead - */

.site-head {
  border-bottom: 1px solid var(--line);
  background: var(--band);
}
.site-head .in {
  max-width: 1040px; margin: 0 auto; padding: 10px 14px;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.brand {
  display: flex; align-items: baseline; gap: 9px;
  color: var(--ink); font-weight: 700; font-size: 17px; letter-spacing: -.01em;
}
.brand:hover { text-decoration: none; }
.brand .sub {
  font-weight: 400; font-size: 12px; color: var(--mut);
  text-transform: uppercase; letter-spacing: .05em;
}

.site-nav { display: flex; gap: 2px; flex-wrap: wrap; margin-left: auto; }
.site-nav a {
  display: block; padding: 6px 11px; border-radius: 6px;
  font-size: 13.5px; color: var(--ink);
}
.site-nav a:hover { background: var(--page); text-decoration: none; }
.site-nav a[aria-current="page"] {
  background: var(--bar); color: #fff; font-weight: 600;
}

/* The search box, wherever it lands. searchinclude.php emits a bare form. */
form#search, .site-search {
  display: flex; gap: 6px; align-items: center;
  font-size: 0; margin: 0;
}
form#search input[type="text"], .site-search input[type="text"] {
  font: 14px var(--sans); color: var(--ink); background: var(--page);
  border: 1px solid var(--line); border-radius: 6px; padding: 6px 10px;
  width: 100%; max-width: 260px; min-width: 0;
}
form#search input[type="text"]:focus, .site-search input[type="text"]:focus {
  outline: 2px solid var(--bar); outline-offset: -1px; border-color: var(--bar);
}
form#search input[type="submit"], .site-search input[type="submit"],
button, input[type="button"] {
  font: 600 13px var(--sans); color: var(--ink); background: var(--page);
  border: 1px solid var(--line); border-radius: 6px; padding: 6px 12px;
  cursor: pointer;
}
form#search input[type="submit"]:hover, button:hover { border-color: var(--bar); color: var(--bar); }

/* --------------------------------------------------------------- content - */

.page { max-width: 1040px; margin: 0 auto; padding: 4px 14px 52px; }

h1, h2, h3, h4 { line-height: 1.25; }
.page > h1, .page > h2:first-of-type, .page > h3:first-of-type { margin-top: 18px; }
h1 { font-size: 26px; margin: 18px 0 4px; }
h2 { font-size: 19px; margin: 30px 0 6px; padding-bottom: 5px; border-bottom: 2px solid var(--line); }
h3 { font-size: 17px; margin: 22px 0 6px; }
h4 { font-size: 14px; margin: 16px 0 4px; text-transform: uppercase;
     letter-spacing: .04em; color: var(--mut); }

.crumbs { font-size: 13px; color: var(--mut); margin: 14px 0 0; }
.crumbs a { color: var(--mut); }
.crumbs a:hover { color: var(--bar); }
.crumbs span { padding: 0 5px; opacity: .55; }

.lede { color: var(--mut); margin: 0 0 16px; }
.muted, .note { color: var(--mut); }
.note { font-size: 13px; }

hr { border: 0; border-top: 1px solid var(--line); margin: 12px 0; }
/* <hr width="30%"> is not a rule in the event listing, it is a LINE BREAK.
   The three cells are each a stack of facts -- name / location / date, and
   director / leg+ / club / cup / results / pics -- separated by one. Drawn as
   actual rules that is six grey lines per row and 33 per screen. Zero height
   keeps the break, which is all it was ever doing. */
td hr, th hr { border: 0; height: 0; margin: 3px 0; width: auto !important; }

/* ---------------------------------------------------------------- tables - */

.scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table {
  border-collapse: collapse;
  font-size: 13.5px;
  background: var(--page);
}
/* Legacy pages set border=2 / border=3 / cellpadding on the tag itself. */
table[border] { border: 0; }
table[border] td, table[border] th { border: 0; border-bottom: 1px solid var(--line); }

th, td { padding: 7px 9px; text-align: left; vertical-align: top; }
th {
  font-size: 11.5px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .03em; color: var(--mut);
  background: var(--soft); border-bottom: 1px solid var(--line);
  vertical-align: bottom;
}
tbody tr:hover > td { background: var(--soft); }

/* bgcolor="lightblue" / "lightgreen" / "yellow" are all over the legacy pages.
   A CSS background beats the attribute, so nothing has to be edited out. */
[bgcolor] { background: transparent; }
tr[bgcolor="lightblue"] > td, td[bgcolor="lightblue"],
tr[bgcolor=lightblue] > td, td[bgcolor=lightblue] { background: var(--soft); }
/* lightgreen and lightblue are not decoration on the event listing: green is
   an event still to come, blue is one within three days. Flattening them threw
   away the only thing on the page that says which races have not happened yet.
   A left edge carries it without tinting a whole row of prose. */
tr[bgcolor="lightgreen"] > td, td[bgcolor="lightgreen"],
tr[bgcolor=lightgreen] > td, td[bgcolor=lightgreen] { background: transparent; }
tr[bgcolor="lightgreen"] > td:first-child, tr[bgcolor=lightgreen] > td:first-child {
  box-shadow: inset 3px 0 0 var(--ok);
}
tr[bgcolor="lightblue"] > td:first-child, tr[bgcolor=lightblue] > td:first-child {
  box-shadow: inset 3px 0 0 var(--acc);
}
/* ...but not on the two-column key/value tables, where every row is blue. */
table[border="2"] tr[bgcolor] > td:first-child { box-shadow: none; }
tr[bgcolor="yellow"] > td, td[bgcolor="yellow"] { background: rgba(226,169,74,.16); }

/* thead in the legacy pages is built from <td>, not <th>. */
thead td {
  font-size: 11.5px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .03em; color: var(--mut); background: var(--soft);
  border-bottom: 1px solid var(--line);
}
thead td b, thead td center { font-weight: 600; }

/* Times, places, distances read as columns of figures. */
td { font-variant-numeric: tabular-nums; }

/* ------------------------------------------- neutralise the old markup --- */

font { font-size: inherit !important; font-family: inherit; }
font[color="green"], font[color=green] { color: var(--ok); font-weight: 600; }
font[color="red"], font[color=red] { color: var(--acc); font-weight: 600; }
font[color="blue"], font[color=blue] { color: var(--bar); }
center { display: block; text-align: center; }
td center { text-align: left; }
big { font-size: 1.05em; }

/* ------------------------------------------------ the event listing page - */

#newsitem > td { border-bottom: 1px solid var(--line); padding: 13px 11px; }
#newsitem:hover > td { background: var(--soft); }
a#event { font-weight: 600; }
td#description { color: var(--ink); white-space: pre-line; max-width: 46ch; }

/* ------------------------------------------------------- panels and tiles */

.panel {
  background: var(--soft); border: 1px solid var(--line);
  border-radius: 8px; padding: 13px 15px; margin: 14px 0;
}
.tiles { display: flex; flex-wrap: wrap; gap: 10px; margin: 14px 0 4px; }
.tile {
  flex: 1 1 140px; background: var(--soft); border: 1px solid var(--line);
  border-radius: 7px; padding: 11px 13px;
}
.tile b { display: block; font-size: 25px; line-height: 1.15; font-variant-numeric: tabular-nums; }
.tile span { font-size: 12px; color: var(--mut); text-transform: uppercase; letter-spacing: .04em; }

/* Key/value rows -- the race page's Distance, Location, Weather, Director.
 *
 * NAMED .kv, NOT .facts, and that is not cosmetic. stats.php already had a
 * "facts" list of its own for Things worth knowing, where <b> is a highlight
 * inside a sentence rather than a label. Naming this one the same turned every
 * one of those sentences into a flex row and gave each bold phrase a fixed
 * 148px column, so the prose came out in ragged stripes.
 *
 * Source order did not save it either: a rule of the form list-li-child-b
 * scores 0-2-1 against the page's own list-b at 0-1-1, so the generic rule won
 * on specificity however late the page's stylesheet loaded. A shared
 * stylesheet has to assume every class name it invents may already mean
 * something on a page it has never read. */
.kv { list-style: none; padding: 0; margin: 12px 0 0; }
.kv li { padding: 8px 0; border-bottom: 1px solid var(--line); display: flex; gap: 14px; }
.kv li > b { flex: 0 0 148px; font-weight: 600; font-size: 12px; color: var(--mut);
             text-transform: uppercase; letter-spacing: .03em; padding-top: 2px; }

.badge {
  display: inline-block; font-size: 11px; font-weight: 600; line-height: 1;
  padding: 4px 7px; border-radius: 999px; letter-spacing: .02em;
  background: var(--soft); color: var(--mut); border: 1px solid var(--line);
}
.badge-yes { color: var(--ok); border-color: currentColor; }
.badge-no { color: var(--no); }

/* ---------------------------------------------------------------- footer - */

.site-foot, footer {
  border-top: 1px solid var(--line);
  margin-top: 40px; padding: 18px 14px 40px;
  color: var(--mut); font-size: 13px;
  background: var(--band);
}
.site-foot .in, footer > .in { max-width: 1040px; margin: 0 auto; }
.site-foot a, footer a { color: var(--bar); }
.site-foot img, footer img { vertical-align: middle; opacity: .7; }

/* ------------------------------------------------------------ responsive - */

@media (max-width: 700px) {
  /* THE PAGE ITSELF MUST NEVER SCROLL SIDEWAYS. A results table is eight
     columns wide and none of them are wrapped in a .scroll div, so on a phone
     the whole document would move rather than the table. Making the table a
     block gives it its own scroll box without touching a line of markup --
     which matters, because the alternative is editing every table on pages
     holding twenty-eight years of results. */
  table { display: block; overflow-x: auto; max-width: 100%; }
  img { max-width: 100%; height: auto; }
  /* A URL pasted into an event description is one unbreakable word. */
  .prose, td#description { overflow-wrap: anywhere; }
  .site-head .in { padding: 9px 12px; gap: 9px; }
  .brand { font-size: 15px; }
  .brand .sub { display: none; }
  .site-nav { margin-left: 0; width: 100%; overflow-x: auto; flex-wrap: nowrap; }
  .site-nav a { padding: 6px 9px; white-space: nowrap; }
  .page { padding: 2px 12px 44px; }
  h1 { font-size: 21px; }
  table { font-size: 12.5px; }
  th, td { padding: 6px 7px; }
  td#description { max-width: none; }
  .kv li { display: block; }
  .kv li > b { display: block; margin-bottom: 2px; }
}

@media print {
  .site-head, .site-foot, footer, .skip, form#search { display: none; }
  body { color: #000; background: #fff; }
  a { color: #000; }
  .page { max-width: none; padding: 0; }
}

/* Descriptions and blurbs. PUBLIC-SITE.md section 5: event.php and race.php
   emit the column through strip_tags(iconv(...)) with no nl2br, so every
   newline collapses to a single space and the whole field arrives as one run
   of prose. That is WHY the club writes in label lines -- "Distance:",
   "Start Time:" -- because a label survives the collapse and a paragraph
   break does not. Honouring the newlines in CSS costs nothing, needs no
   change to how anyone writes, and puts the label lines back on lines. */
.prose { white-space: pre-line; max-width: 76ch; }

/* The event listing: three stacks of facts rather than a grid of prose. */
#newsitem > td:first-child { min-width: 15em; }
#newsitem > td:last-child { font-size: 12.5px; color: var(--mut); white-space: nowrap; }
#newsitem > td:last-child a { white-space: normal; }

/* ---------------------------------------------- personal bests & milestones - */
/* Added 2026-08-15 with the profile's Personal Bests and Milestones blocks. */
/* ⚠️ THE MILESTONES LIST MUST NOT BORROW .kv, AND IT DID FOR AN AFTERNOON.
   .kv is a KEY/value layout: `li` is a flex row and `li > b` is a fixed 148px
   uppercase 12px label column. The milestone lines are sentences whose <b> marks
   a NUMBER inside the prose, so every figure was rendered as a tiny raised label
   with a 148px gutter after it - "11        races recorded, from  2011".
   Reported from /profile/805. Its own styling now, and no shared class. */
.milestones { list-style: none; padding: 0; margin: 10px 0 0; }
.milestones li { padding: 6px 0; border-bottom: 1px solid var(--line); }
.milestones li:last-child { border-bottom: 0; }
.milestones b { font-weight: 600; }
.pbstar { color: #b8860b; font-size: 0.95em; }
@media (prefers-color-scheme: dark) { .pbstar { color: #e3b341; } }
tr.pb > td:first-child { font-weight: 600; }

/* ------------------------------------------------------- sortable tables - */
/* Progressive enhancement: js/sort.js adds these classes and the click
   handlers. Without JavaScript the header is an ordinary cell and the table
   is exactly what it was - which matters, because these tables are the
   archive and must never depend on a script to be readable. */
th.sortable-th { cursor: pointer; user-select: none; white-space: nowrap; }
th.sortable-th:hover { text-decoration: underline; }
th.sortable-th::after { content: " \2195"; opacity: .35; font-size: .85em; }
th.sortable-th[aria-sort="ascending"]::after  { content: " \25B2"; opacity: .8; }
th.sortable-th[aria-sort="descending"]::after { content: " \25BC"; opacity: .8; }
