/* The racer's instrument (docs/design/mocks/racer.html) is the reference for everything here:
   black on white with thin rules for the day, a dark broadcast theme, red on black for the night.
   Big condensed numerals; colour only carries meaning: orange = course marks, red = a violation,
   green = gaining / done, yellow = waiting for something, purple = best in the race.
   Fonts: Fira Sans when it could be loaded, else the phone's own sans and condensed faces. */

:root {
  --white: #FFFFFF; --black: #000000;
  --bg: #FFFFFF; --bg2: #F4F4F4; --card: #FFFFFF; --fg: #000000; --muted: #5F6366; --line: #D9DADB; --strong: #000000;
  --accent: #000000; --accent-fg: #FFFFFF;
  --warn: #E10600; --warn-bg: #E10600; --warn-fg: #FFFFFF;
  --caution: #8A6D00; --caution-bg: #FFD400; --caution-fg: #000000;
  --ok: #00873E; --ok-bg: #00873E; --ok-fg: #FFFFFF;
  --mark: #FF5A00; --gate: #C98A00; --best: #7B2BD9;
  --sans: 'Fira Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --cond: 'Fira Sans Extra Condensed', 'Roboto Condensed', 'sans-serif-condensed', 'Arial Narrow', sans-serif-condensed, sans-serif;
  --gap: 12px;
  color-scheme: light;
}
/* dark: the broadcast */
:root[data-theme="dark"] {
  --bg: #15181C; --bg2: #1A1D21; --card: #101215; --fg: #F2F3F4; --muted: #9AA0A6; --line: #2A2E33; --strong: #F2F3F4;
  --accent: #F2F3F4; --accent-fg: #0E1012;
  --warn: #FF453A; --warn-bg: #FF453A; --warn-fg: #000000;
  --caution: #FFD60A; --caution-bg: #FFD60A; --caution-fg: #000000;
  --ok: #2BD576; --ok-bg: #2BD576; --ok-fg: #000000;
  --mark: #FF6A13; --gate: #FFB020; --best: #B57BFF;
  color-scheme: dark;
}
/* night: red on black, like an instrument's night backlight — keeps the eyes dark-adapted */
:root[data-theme="night"] {
  --bg: #000000; --bg2: #0A0202; --card: #000000; --fg: #FF2B1C; --muted: #B3241A; --line: #3A0E0A; --strong: #FF2B1C;
  --accent: #FF2B1C; --accent-fg: #000000;
  --warn: #FF2B1C; --warn-bg: #FF2B1C; --warn-fg: #000000;
  --caution: #FF2B1C; --caution-bg: #FF2B1C; --caution-fg: #000000;
  --ok: #FF2B1C; --ok-bg: #FF2B1C; --ok-fg: #000000;
  --mark: #FF2B1C; --gate: #FF2B1C; --best: #FF2B1C;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--fg); }
body { font: 16px/1.45 var(--sans); -webkit-tap-highlight-color: transparent; }
main { max-width: 640px; margin: 0 auto; padding: 12px 16px calc(24px + env(safe-area-inset-bottom)); }
.n, .num { font-family: var(--cond); font-variant-numeric: tabular-nums; }
h1, h2 { font-family: var(--cond); font-style: italic; font-weight: 700; text-transform: uppercase; letter-spacing: .01em; line-height: 1; }
h1 { font-size: 30px; margin: 12px 0 8px; }
h2 { font-size: 22px; margin: 28px 0 10px; }
a { color: var(--fg); }
:focus-visible { outline: 3px solid var(--mark); outline-offset: 2px; }
.muted { color: var(--muted); }
.small { font-size: 14px; }
.pad { padding: 16px; }
.row { display: flex; gap: var(--gap); align-items: center; }
.row > * { flex: 1; min-width: 0; }
/* fields side by side: the inputs line up even when one label wraps */
.row > .field { align-self: flex-end; }
.row > .field + .field { margin-top: 0; }
.row.between { justify-content: space-between; }
.stack > * + * { margin-top: var(--gap); }
/* a "card" is a block between rules, not a floating box */
.card { background: var(--card); border-top: 1px solid var(--strong); padding: 14px 0; }
.card + .card { margin-top: 0; }
[hidden] { display: none !important; }

button, .btn {
  display: flex; align-items: center; justify-content: center; width: 100%; min-height: 52px; border: 0; border-radius: 0; padding: 12px 16px;
  font: 600 16px/1.2 var(--sans); background: var(--accent); color: var(--accent-fg); cursor: pointer; text-decoration: none;
}
button.secondary { background: transparent; color: var(--fg); box-shadow: inset 0 0 0 1px var(--strong); }
button.danger { background: transparent; color: var(--warn); box-shadow: inset 0 0 0 1px var(--line); }
button:disabled { opacity: .45; }
label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 4px; letter-spacing: .02em; }
input, select {
  width: 100%; min-height: 50px; padding: 10px 12px; font: inherit; color: var(--fg);
  background: var(--card); border: 1px solid var(--strong); border-radius: 0;
}
input[type="checkbox"] { width: 24px; min-height: 24px; height: 24px; accent-color: var(--accent); }
.check { display: flex; gap: 10px; align-items: center; color: var(--fg); font-size: 16px; }
.field + .field { margin-top: var(--gap); }

.code { font: 700 56px/1 var(--cond); letter-spacing: .08em; text-align: center; }
.code-input { text-transform: uppercase; letter-spacing: .2em; font: 700 24px var(--cond); }

.list { list-style: none; margin: 0; padding: 0; }
.list li { padding: 12px 0; border-bottom: 1px solid var(--line); }
.list li:last-child { border-bottom: 0; }
.list button { display: block; text-align: left; background: none; color: var(--fg); min-height: 0; padding: 0; font-weight: 400; box-shadow: none; }

.head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.status { font-size: 14px; color: var(--muted); }
.offline { color: var(--warn); font-size: 14px; }

/* segmented switches: window of the chart, value of a block, fact / handicap */
.segs { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: 1px solid var(--strong); }
.segs + .segs { margin-top: 6px; }
button.seg { min-height: 36px; padding: 4px; background: transparent; color: var(--fg); font-weight: 500; font-size: 14px; box-shadow: none; border-left: 1px solid var(--strong); }
button.seg:first-child { border-left: 0; }
button.seg[aria-pressed="true"] { background: var(--accent); color: var(--accent-fg); }

/* ---------- app bar ---------- */
.appbar { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 0 16px; border-bottom: 1px solid var(--strong); }
.appbar .brand { display: flex; align-items: center; gap: 8px; font: italic 700 20px/1 var(--cond); text-transform: uppercase; text-decoration: none; margin-right: auto; }
.appbar .ttl { font-weight: 600; font-size: 14px; flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-decoration: none; }
.appbar .clock { font: 700 28px/1 var(--cond); font-variant-numeric: tabular-nums; }
.appbar .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); flex: 0 0 auto; }
.appbar .dot.off { background: var(--warn); }
.theme { width: 40px; min-height: 36px; height: 36px; padding: 0; flex: 0 0 auto; background: transparent; color: var(--fg); box-shadow: inset 0 0 0 1px var(--line); }
.theme svg { width: 18px; height: 18px; }

/* ---------- home ---------- */
.home h1 { margin-top: 20px; }
.races { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--strong); }
.races li { border-bottom: 1px solid var(--line); }
.races button { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; width: 100%; padding: 12px 0; min-height: 0; background: none; color: var(--fg); box-shadow: none; text-align: left; font-weight: 400; }
.races b { display: block; font-weight: 600; }
.races .sub { font-size: 13px; color: var(--muted); }
.races .t { font: 700 22px/1 var(--cond); font-variant-numeric: tabular-nums; text-align: right; }
.races .live { display: block; font-size: 12px; font-weight: 600; color: var(--warn); text-align: right; }
.home .appbar, main > .appbar { margin: -12px -16px 8px; }
.codebox { margin-top: 16px; }
.races .sub { display: block; }
.acts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-top: 20px; }

/* ---------- the race: one screen, full-screen pages and tabs on a phone, everything at once on a wide screen ---------- */
main.race { max-width: none; padding: 0; display: flex; flex-direction: column; height: 100vh; height: 100dvh; }
.race .net { padding: 0 16px; }
.race .net:empty { display: none; }
.race .pages { flex: 1 1 auto; min-height: 0; position: relative; }
.race .pg { position: absolute; inset: 0; overflow: auto; display: none; flex-direction: column; }
.race .pg.on { display: flex; }
.race .pg.mappg { overflow: hidden; }
.race .pg .in { padding: 0 16px 20px; }
.tabs { flex: 0 0 auto; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); height: 58px; border-top: 1px solid var(--line); padding-bottom: env(safe-area-inset-bottom); box-sizing: content-box; }
.tab { position: relative; flex-direction: column; gap: 3px; min-height: 0; height: 58px; padding: 0; background: transparent; color: var(--muted); font: 500 12px var(--sans); box-shadow: none; }
.tab svg { width: 22px; height: 22px; }
.tab[aria-current] { color: var(--fg); font-weight: 600; }
.tab[aria-current]::before { content: ""; position: absolute; top: -1px; left: 22%; right: 22%; height: 3px; background: var(--fg); }
.tab .badge { position: absolute; top: 7px; left: calc(50% + 6px); min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--warn); color: var(--warn-fg); font: 700 12px/18px var(--cond); }

/* the alert: a full-width bar seen from the corner of the eye, on every page */
.alert { padding: 12px 16px; display: flex; gap: 12px; align-items: center; }
.alert b { display: block; font: 700 22px/1.05 var(--cond); text-transform: uppercase; letter-spacing: .02em; }
.alert span { font-size: 15px; }
.alert.red { background: var(--warn-bg); color: var(--warn-fg); }
.alert.yellow { background: var(--caution-bg); color: var(--caution-fg); }
.alert.green { background: var(--ok-bg); color: var(--ok-fg); }

/* instrument readings */
.phase { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 12px 16px 0; }
.phase b { font: italic 700 20px/1 var(--cond); text-transform: uppercase; letter-spacing: .02em; }
.phase span { font-size: 13px; color: var(--muted); }
.read { padding: 8px 16px 10px; border-bottom: 1px solid var(--line); display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; column-gap: 12px; }
.read .l, .cells .l, .dir .l { font-size: 12px; color: var(--muted); letter-spacing: .04em; text-transform: uppercase; }
.read .l { grid-column: 1 / -1; }
.read .v { font-family: var(--cond); font-weight: 700; font-variant-numeric: tabular-nums; line-height: .9; letter-spacing: -.02em; white-space: nowrap; }
.read .v small { font-size: .38em; font-weight: 600; letter-spacing: 0; margin-left: 4px; }
.read .side { text-align: right; font-size: 13px; color: var(--muted); padding-bottom: 4px; }
.read .side b { display: block; font: 700 36px/1 var(--cond); color: var(--fg); font-variant-numeric: tabular-nums; }
.xl { font-size: 120px; } .lg { font-size: 84px; } .md { font-size: 64px; }
.cells { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); border-bottom: 1px solid var(--line); }
.cells > div { padding: 8px 16px; }
.cells > div + div { border-left: 1px solid var(--line); }
.cells .v { font: 700 36px/1 var(--cond); font-variant-numeric: tabular-nums; white-space: nowrap; }
.cells .v.best { color: var(--best); }
.cells .v.warn { color: var(--warn); }
.cells .v small { font-size: 18px; color: var(--muted); }
/* trend beside the speed: the arrow and the block-to-block change */
.trend { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; padding-bottom: 6px; }
.trend .arrow { width: 0; height: 0; border-left: 14px solid transparent; border-right: 14px solid transparent; }
.trend .arrow.up { border-bottom: 22px solid var(--ok); }
.trend .arrow.down { border-top: 22px solid var(--warn); }
.trend b { font: 700 18px/1 var(--cond); }
.trend b.up { color: var(--ok); } .trend b.down { color: var(--warn); }
/* direction to the mark: the dial, the boat's bow up, the mark an orange dot on the ring */
.dir { display: grid; grid-template-columns: 104px minmax(0, 1fr); column-gap: 18px; align-items: center; padding: 8px 16px; border-bottom: 1px solid var(--line); }
.dial { display: block; width: 104px; height: 104px; overflow: visible; }
.dial .ring { fill: none; stroke: var(--line); stroke-width: 1.5; }
.dial .ticks { stroke: var(--muted); stroke-width: 1.5; }
.dial .lubber { stroke: var(--fg); stroke-width: 3; }
.dial .north { font: 600 11px var(--sans); fill: var(--muted); text-anchor: middle; }
.dial .ray { stroke: var(--mark); stroke-width: 3; stroke-linecap: round; }
.dial .boat { fill: var(--fg); }
.dial .mk { fill: var(--mark); stroke: var(--bg); stroke-width: 2; }
.dir .v { display: flex; align-items: baseline; font: 700 84px/.9 var(--cond); letter-spacing: -.02em; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dir .v .deg { align-self: flex-start; width: .2em; height: .2em; margin: .02em 0 0 .05em; border: .045em solid currentColor; border-radius: 50%; }
.dir .v .w { font-size: 30px; letter-spacing: 0; margin-left: 10px; }
.dir .sub { font-size: 13px; color: var(--muted); margin-top: 8px; }
/* the start procedure as a line with the signals on it */
.seq { margin: 6px 16px 4px; position: relative; height: 40px; }
.seq .track { position: absolute; left: 0; right: 0; top: 16px; height: 2px; background: var(--line); }
.seq .done { position: absolute; left: 0; top: 15px; height: 4px; background: var(--fg); }
.seq .tick { position: absolute; top: 10px; width: 2px; height: 14px; background: var(--fg); }
.seq .tick span { position: absolute; top: 18px; left: 50%; transform: translateX(-50%); font: 600 12px/1 var(--cond); white-space: nowrap; }
.seq .tick:last-child span { left: auto; right: 0; transform: none; }
/* speed chart */
canvas.speed { display: block; width: 100%; height: 112px; margin: 6px 0 4px; grid-column: 1 / -1; }
.speedctl { padding: 6px 16px 10px; border-bottom: 1px solid var(--line); }
.speedctl .note { font-size: 12px; color: var(--muted); margin-top: 6px; }

/* standings */
.tw { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--strong); }
.tw li { display: grid; grid-template-columns: 30px 4px minmax(0, 1fr) auto; column-gap: 10px; align-items: center; min-height: 48px; padding: 4px 0; border-bottom: 1px solid var(--line); }
.tw .p { font: 700 24px/1 var(--cond); text-align: right; }
.tw .c { height: 22px; background: var(--line); }
.tw .nm { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw .nm small { font-weight: 400; color: var(--muted); margin-left: 6px; }
.tw .g { font: 500 17px/1.1 var(--cond); color: var(--muted); text-align: right; max-width: 52vw; }
.tw li.me { background: var(--bg2); }
.tw li.me .c { background: var(--fg); }
.tw li.lead .p { color: var(--best); }

/* events; each violation says what to do and whether it was done */
.feed { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--strong); font-size: 15px; }
.feed li { display: grid; grid-template-columns: 70px minmax(0, 1fr); padding: 10px 0; border-bottom: 1px solid var(--line); }
.feed li.me { background: var(--bg2); }
.feed time { font: 500 16px/1.3 var(--cond); color: var(--muted); font-variant-numeric: tabular-nums; }
.feed .muted { grid-column: 1 / -1; }
.req { font-size: 14px; color: var(--muted); margin-top: 4px; padding-left: 10px; border-left: 3px solid var(--line); }
.req.open { border-left-color: var(--caution-bg); } .req.open b { color: var(--caution); }
.req.done { border-left-color: var(--ok); } .req.done b { color: var(--ok); }
.req.failed { border-left-color: var(--warn); } .req.failed b { color: var(--warn); }

/* the map fills its page; at night it turns red too */
canvas.map { display: block; width: 100%; height: 56vh; max-height: 460px; min-height: 260px; background: var(--bg2); }
canvas.map.small { height: 220px; min-height: 0; }
.mappg canvas.map { flex: 1 1 auto; height: auto; max-height: none; min-height: 0; }
:root[data-theme="night"] canvas.map { filter: grayscale(1) sepia(1) hue-rotate(-50deg) saturate(5) brightness(.75); }

table { width: 100%; border-collapse: collapse; font-size: 15px; }
td, th { padding: 8px 4px; border-bottom: 1px solid var(--line); text-align: left; }
th { color: var(--muted); font-weight: 400; font-size: 12px; letter-spacing: .04em; }

.qr-wrap { display: flex; justify-content: center; }
canvas.qr { image-rendering: pixelated; background: #FFFFFF; padding: 8px; }

.toast {
  position: fixed; left: 16px; right: 16px; bottom: calc(76px + env(safe-area-inset-bottom)); z-index: 10;
  max-width: 480px; margin: 0 auto; background: var(--fg); color: var(--bg); padding: 12px 16px; text-align: center; font-weight: 500;
}

/* wide screens: the broadcast — the map in the middle, standings and the instrument on the left, events on the right */
@media (min-width: 960px) {
  main { padding-top: 24px; }
  .race .tabs { display: none; }
  /* the left column scrolls with the page; the map and the events stay the height of the screen */
  .race .pages { display: grid; grid-template-columns: minmax(300px, 360px) minmax(0, 1fr) minmax(300px, 380px); grid-template-rows: auto auto 1fr;
                 align-items: start; overflow-y: auto; }
  .race .pg { position: static; display: flex; overflow: visible; }
  .race .pg.inst { grid-column: 1; grid-row: 1; }
  .race .pg.towerpg { grid-column: 1; grid-row: 2; padding-top: 8px; }
  .race .pg.ctlpg { grid-column: 1; grid-row: 3; }
  .race .pg.mappg { grid-column: 2; grid-row: 1 / 4; position: sticky; top: 0; height: calc(100vh - 54px); border-left: 1px solid var(--line); border-right: 1px solid var(--line); }
  .race .pg.feedpg { grid-column: 3; grid-row: 1 / 4; position: sticky; top: 0; max-height: calc(100vh - 54px); overflow: auto; padding-top: 8px; }
  .lg { font-size: 72px; } .xl { font-size: 96px; }
}

/* the recorder's journal: long lines wrap, the newest lines are at the bottom */
pre.journal {
  margin: 0; padding: 8px; max-height: 55vh; overflow: auto; background: var(--bg2); border: 1px solid var(--line);
  font: 11px/1.4 ui-monospace, Menlo, Consolas, monospace; white-space: pre-wrap; word-break: break-all;
}
