/* Bootsplan — local planning surface.
   Each colour answers one question, the same way on every screen:
     navy and blue  who chose the boat: dark navy held by hand, blue by the solver
     brown ramp     how heavy a rower or a hull is, light sand to dark brown
     class colours  which boat class: aqua 1x, violet 2x, pink fours, yellow eights
     red, orange    the validator: red must be fixed, orange should be looked at
     green          the crew fits its boat
     light blue     a slalom, placed anywhere inside its block
     yellow         the row under the pointer or picked in the chart
   Colour is never the only signal; every state is also stated in words or in a
   label beside it. The class and weight colours were checked for colour-blind
   separation and step order with the dataviz palette validator. */

:root {
  --ink: #17212c;
  --muted: #5d6874;
  --navy: #1f3b5b;
  --navy-soft: #edf2f8;
  --planned: #4f8fdc;
  --focus: #2a78d6;
  --good: #0ca30c;
  --good-ink: #1f7a1f;
  --warn: #e8743e;
  --warn-ink: #a8431a;
  --warn-soft: #fde8dd;
  --error: #d03b3b;
  --error-soft: #fbeceb;
  --info: #86b6ef;
  --highlight: #fff1b8;
  --highlight-edge: #e0a100;
  --rule: #e2e7ed;
  --rule-strong: #cbd3dc;
  --canvas: #f5f7fa;
  --surface: #ffffff;
  --control: #eef2f6;
  --control-hover: #e2e8ef;
  --ring: 0 0 0 3px rgb(74 139 224 / 32%);
  --shadow-pop: 0 10px 30px rgb(23 33 44 / 14%), 0 2px 6px rgb(23 33 44 / 8%);
  --locked: #7b8894;
  --rest: #b4c2d1;
  --paper: #ffffff;
  --row-alt: #f8fafc;
  --radius: 7px;

  /* Weight, light to heavy: one hue, stepped in lightness. */
  --w1: #cfa262;
  --w2: #b8863f;
  --w3: #9a6a26;
  --w4: #7a4f15;
  --w5: #55330a;

  /* Boat class by crew size. */
  --seat-1: #1baf7a;
  --seat-1-ink: #062e1f;
  --seat-2: #4a3aa7;
  --seat-2-ink: #ffffff;
  --seat-4: #e87ba4;
  --seat-4-ink: #3f0b22;
  --seat-8: #eda100;
  --seat-8-ink: #2e2000;

  --slalom: #cde2fb;
  --slalom-ink: #184f95;
}

/* ---- shared colour marks -------------------------------------------------- */

[data-weight="1"] { --w: var(--w1); }
[data-weight="2"] { --w: var(--w2); }
[data-weight="3"] { --w: var(--w3); }
[data-weight="4"] { --w: var(--w4); }
[data-weight="5"] { --w: var(--w5); }
[data-seats="1"] { --seat: var(--seat-1); --seat-ink: var(--seat-1-ink); }
[data-seats="2"] { --seat: var(--seat-2); --seat-ink: var(--seat-2-ink); }
[data-seats="4"] { --seat: var(--seat-4); --seat-ink: var(--seat-4-ink); }
[data-seats="8"] { --seat: var(--seat-8); --seat-ink: var(--seat-8-ink); }

.class-chip {
  display: inline-block;
  min-width: 2.3rem;
  padding: 0.05rem 0.35rem;
  border-radius: 5px;
  background: var(--seat, var(--rule));
  color: var(--seat-ink, var(--ink));
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1.35;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.chips { display: flex; gap: 0.3rem; flex-wrap: wrap; }

.weight-chip {
  display: inline-block;
  padding: 0.05rem 0.4rem;
  border-left: 4px solid var(--w, var(--rule));
  border-radius: 2px;
  background: color-mix(in srgb, var(--w, var(--rule)) 26%, #fff);
  color: var(--ink);
  font-size: 0.88rem;
  white-space: nowrap;
}
.weight-chip[data-weight=""] { color: var(--muted); font-style: italic; }

.discipline-chip {
  display: inline-block;
  padding: 0.02rem 0.45rem;
  border-radius: var(--radius);
  background: var(--slalom);
  color: var(--slalom-ink);
  font-size: 0.85rem;
  font-weight: 600;
}

/* Selects take the colour of what they hold, so a column of them reads like a
   column of chips. */
select[data-weight]:not([data-weight=""]) {
  border-left: 5px solid var(--w);
  background: color-mix(in srgb, var(--w) 22%, #fff);
}
select[data-seats]:not([data-seats=""]) {
  border-left: 5px solid var(--seat);
  background: color-mix(in srgb, var(--seat) 14%, #fff);
  font-weight: 600;
}
select[data-art="slalom"] {
  border-left: 5px solid var(--slalom-ink);
  background: var(--slalom);
  color: var(--slalom-ink);
  font-weight: 600;
}
select[data-fixed="true"] {
  border: 1px solid var(--navy);
  border-left: 5px solid var(--navy);
  font-weight: 600;
}

/* Weighing is about weight, so it carries the weight colour. */
.weigh { background: color-mix(in srgb, var(--w2) 22%, var(--paper)); }
.weigh input[type="checkbox"] { accent-color: var(--w4); }

* { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  font-size: 0.95rem;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

h1 { font-size: 1.15rem; margin: 0; font-weight: 700; letter-spacing: -0.01em; }
a { color: var(--navy); }

/* ---- controls ---------------------------------------------------------------
   One height, one radius and one focus ring for every button, field and menu.
   Filled navy is the one action that matters on a screen; everything else is
   a soft grey button that does not compete with the plan. */
button, .button {
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  line-height: 1.2;
  min-height: 2.25rem;
  padding: 0.5rem 0.95rem;
  border: 1px solid transparent;
  background: var(--navy);
  color: #fff;
  border-radius: var(--radius);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  transition: background-color 120ms ease, box-shadow 120ms ease, color 120ms ease;
}
button:hover, .button:hover { background: #27496f; }
button.quiet, .button.quiet { background: var(--control); color: var(--ink); }
button.quiet:hover, .button.quiet:hover { background: var(--control-hover); }
button:disabled { opacity: 0.45; cursor: default; }
button:focus-visible, .button:focus-visible, select:focus-visible, input:focus-visible,
[draggable]:focus-visible, a:focus-visible {
  outline: none;
  box-shadow: var(--ring);
}

input[type="text"], input[type="email"], input[type="number"], input[type="date"],
input[type="time"], input:not([type]), select {
  font: inherit;
  font-size: 0.92rem;
  color: var(--ink);
  min-height: 2.25rem;
  padding: 0.4rem 0.65rem;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  background: var(--surface);
  transition: border-color 120ms ease, box-shadow 120ms ease;
}
input:hover, select:hover { border-color: #aeb9c6; }
input:focus, select:focus { outline: none; border-color: var(--planned); box-shadow: var(--ring); }
input::placeholder { color: #8a95a2; }
select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235b6673' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.65rem center;
  cursor: pointer;
}
input[type="checkbox"] { width: 1.05rem; height: 1.05rem; accent-color: var(--navy); }

/* ---- header -----------------------------------------------------------------
   A light bar: the app, the regatta, its views as tabs, and the account. */
.bar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 0.5rem 1.4rem;
  min-height: 3.6rem;
  padding: 0.45rem 1.5rem;
  flex-wrap: nowrap;
  background: rgb(255 255 255 / 92%);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
}
.bar h1 {
  color: var(--ink);
  flex: 0 1 auto;
  min-width: 0;
  max-width: 30rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-left: 1.2rem;
  border-left: 1px solid var(--rule);
}

/* The toolbar sits under the header as one strip. Groups are separated by
   space and a hairline rather than by boxes. */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0;
  padding: 0.6rem 1.5rem;
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
}
.tools {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0 0.9rem;
  border-left: 1px solid var(--rule);
}
.tools:first-child { padding-left: 0; border-left: none; }
.tools-end { margin-left: auto; border-left: none; padding-right: 0; }

.views, .days { display: flex; gap: 0.2rem; flex-wrap: wrap; }
.views { flex: none; }
.brand { flex: none; }
.bar-end { flex: none; }
.views button, .days button {
  min-height: 2.1rem;
  padding: 0.35rem 0.8rem;
  background: transparent;
  color: var(--muted);
  font-weight: 600;
  border-radius: 999px;
}
.views button:hover, .days button:hover { background: var(--control); color: var(--ink); }
.views button[aria-current="true"], .days button[aria-current="true"],
.days button[aria-pressed="true"] {
  background: var(--navy-soft);
  color: var(--navy);
}

.status {
  margin: 0;
  padding: 0.55rem 1.5rem;
  font-size: 0.9rem;
  color: var(--muted);
  background: var(--canvas);
  min-height: 2.3rem;
}
.status[data-tone="error"] { color: #a02525; background: var(--error-soft); }
.status[data-tone="good"] { color: var(--good-ink); }

main { padding: 0 1.5rem 3rem; }
.view[hidden] { display: none; }
/* Day tabs, the day's progress and the chart order share one line. */
.plan-head {
  display: flex;
  align-items: center;
  gap: 0.6rem 1.6rem;
  flex-wrap: wrap;
  padding: 0.7rem 0 0;
}
.plan-head .segmented { margin-left: auto; }

.meter { display: flex; align-items: center; gap: 0.75rem; }
.meter-bar {
  display: flex;
  width: 11rem;
  height: 0.6rem;
  border-radius: 999px;
  overflow: hidden;
  background: var(--rule);
}
.meter-fixed { background: var(--navy); }
.meter-planned { background: var(--planned); }
.meter-open { background: var(--error); }
.meter-words { display: flex; gap: 0.9rem; font-size: 0.85rem; color: var(--muted); }
.meter-word::before {
  content: "";
  display: inline-block;
  width: 0.6rem; height: 0.6rem;
  margin-right: 0.3rem;
  border-radius: 2px;
  vertical-align: 0;
}
.meter-word-fixed::before { background: var(--navy); }
.meter-word-planned::before { background: var(--planned); }
.meter-word-open { color: var(--error); font-weight: 600; }
.meter-word-open::before { background: var(--error); }

/* Two-way switch: a pair of buttons joined into one control. */
.segmented {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: calc(var(--radius) + 3px);
  background: var(--control);
}
.segmented button {
  min-height: 1.95rem;
  padding: 0.3rem 0.8rem;
  background: transparent;
  color: var(--muted);
  font-size: 0.87rem;
  border-radius: var(--radius);
}
.segmented button:hover { background: rgb(255 255 255 / 60%); color: var(--ink); }
.segmented button[aria-pressed="true"] {
  background: var(--surface);
  color: var(--navy);
  box-shadow: 0 1px 2px rgb(23 33 44 / 12%), 0 0 0 1px rgb(23 33 44 / 4%);
}
.day-count { margin-left: 0.45rem; font-weight: 500; font-size: 0.85rem; color: var(--muted); }

.plot {
  margin: 0.8rem 0 0.4rem;
  padding: 0.3rem 0.9rem 0.8rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: calc(var(--radius) + 3px);
}

/* ---- boat-occupancy chart -------------------------------------------------
   One row per boat, and inside a row two bands that never overlap: the bar band
   carries the boat in use and the crew's names, the rail band underneath it
   carries the rest it owes afterwards. The pill says who chose the boat — dark
   navy held by hand, blue by the solver — unless the validator objects, in
   orange or red. The name column carries the class chip and, on its left edge,
   the weight of the boat. */

.timeline { position: relative; }
.tl-head, .tl-row {
  display: grid;
  grid-template-columns: var(--tl-name-column) 1fr;
  align-items: stretch;
}
.timeline { --tl-name-column: 11.5rem; }

.tl-head {
  position: sticky;
  top: 0;
  z-index: 7;
  height: 1.8rem;
  border-bottom: 1px solid var(--rule);
  background: var(--canvas);
  color: var(--muted);
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  top: 3.6rem;
}
.tl-hours { position: relative; }
.tl-hour {
  position: absolute;
  bottom: 0.2rem;
  transform: translateX(-50%);
  padding: 0 0.15rem;
}
/* The last hour sits on the right edge; centred, half of it would be cut off. */
.tl-hour:last-child { transform: translateX(-100%); }

.tl-row {
  height: 2.3rem;
  border-top: 1px solid var(--rule);
}
.tl-row:nth-child(even) { background: var(--row-alt); }
/* Tracing one boat across eleven hours is easier with the row lit up. */
.tl-row:hover { background: var(--navy-soft); }
.tl-row[data-new-class="true"] { border-top: 1px solid var(--navy); }
.tl-row:last-child { border-bottom: 1px solid var(--rule); }

.tl-name {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
  padding: 0 0.7rem 0 0.55rem;
  box-shadow: inset 5px 0 0 var(--w, transparent);
  font-size: 0.88rem;
  white-space: nowrap;
  overflow: hidden;
}
.tl-boat { overflow: hidden; text-overflow: ellipsis; }
.tl-name .class-chip { flex: none; min-width: 2.1rem; font-size: 0.78rem; }
.tl-uses {
  flex: none;
  margin-left: auto;
  color: var(--muted);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}
.tl-row[data-idle="true"] .tl-boat { color: var(--muted); }
.tl-row[data-idle="true"] .class-chip { opacity: 0.45; }

.tl-track { position: relative; overflow: hidden; }
.tl-track.drop { background: color-mix(in srgb, var(--good) 16%, var(--paper)); }
.tl-grid { position: absolute; inset: 0; }
.tl-line {
  position: absolute; top: 0; bottom: 0; width: 1px;
  background: var(--rule);
  opacity: 0.55;
}
.tl-line[data-hour="true"] { opacity: 1; }

/* One use of a boat, drawn as three stretches in one row:
     the pill   — the crew fetching the boat, up to their start
     the block  — the hour after the start, nobody else gets it
     the buffer — the hour after that, kept free if at all possible
   The two bands are always neutral. They are a fact about the boat's day, not
   about the crew, and tinting them with the validator's verdict on the crew
   turned whole rows into warnings and buried the findings that are about time. */

.tl-band {
  position: absolute;
  top: 0.55rem;
  height: 0.6rem;
  border-radius: 2px;
}
.tl-hard { background: var(--rest); }
.tl-buffer {
  background: color-mix(in srgb, var(--rest) 42%, var(--paper));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rest) 55%, var(--paper));
}

/* Where the next crew reaches into something they should not. Hatching is kept
   for these two alone, so anything striped on the chart is a finding. */
.tl-taken {
  z-index: 3;
  background: repeating-linear-gradient(
    -45deg,
    var(--error) 0 3px,
    color-mix(in srgb, var(--error) 50%, var(--paper)) 3px 7px
  );
}
.tl-eaten {
  z-index: 3;
  background: repeating-linear-gradient(
    -45deg,
    var(--warn) 0 3px,
    color-mix(in srgb, var(--warn) 40%, var(--paper)) 3px 7px
  );
}

/* The pill: the boat is on its way to the water. */
.tl-bar {
  position: absolute;
  top: 0.28rem;
  height: 1.15rem;
  min-width: 5px;
  z-index: 2;
  background: var(--planned);
  border-radius: 3px;
  cursor: grab;
  overflow: hidden;
}
.tl-bar[data-state="fixed"] { background: var(--navy); }
.tl-bar[data-state="warning"] { background: var(--warn); }
.tl-bar[data-state="error"] { background: var(--error); }
/* A held pill that the validator objects to keeps the conflict colour and takes
   a navy frame, because losing the colour would hide the one case that has to
   be sorted out by hand. */
.tl-bar[data-fixed="true"][data-state="warning"],
.tl-bar[data-fixed="true"][data-state="error"] {
  box-shadow: inset 0 0 0 2px var(--navy), 0 0 0 1px var(--navy);
}
.tl-bar[data-selected="true"] {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
  z-index: 5;
}
.tl-bar:focus-visible { outline: 2px solid var(--ink); outline-offset: 1px; }
.tl-bar:active { cursor: grabbing; }

/* The crew, written into the row beside their pill. Backed in paper because it
   sits over the block and the buffer and has to stay readable against both. */
.tl-crew {
  position: absolute;
  top: 0.3rem;
  z-index: 4;
  padding: 0 0.3rem;
  max-width: 100%;
  border-radius: 2px;
  background: rgb(253 253 252 / 88%);
  color: var(--ink);
  font-size: 0.8rem;
  line-height: 1.15rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
.tl-crew[data-fixed="true"] { color: var(--muted); }
.tl-code {
  margin-right: 0.35rem;
  color: var(--navy);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.tl-heavy { margin-right: 0.25rem; color: var(--warn-ink); font-size: 0.8rem; }

/* The athlete chart: after each start, the pause the rower is owed, drawn as
   a rail under the label so the label never hides it. */
#timeline[data-mode="athletes"] .tl-band { top: 1.55rem; height: 0.4rem; }
.tl-rest {
  background: color-mix(in srgb, var(--navy) 30%, var(--paper));
}
.tl-bar[data-state="open"] {
  background: var(--paper);
  box-shadow: inset 0 0 0 2px var(--error);
}
.tl-bar[data-estimated="true"] {
  background-image: repeating-linear-gradient(
    90deg, transparent 0 4px, rgb(255 255 255 / 35%) 4px 6px
  );
}

/* One entry under the pointer, lit in the chart and the table together. */
.tl-bar[data-linked="true"] { outline: 2px solid var(--highlight-edge); outline-offset: 1px; z-index: 5; }
#entries tr[data-linked="true"] { background: var(--highlight); }


.lock-icon {
  width: 1.05rem;
  height: 1.05rem;
  flex: none;
}

.icon-button { display: inline-flex; align-items: center; gap: 0.35rem; }

/* Held and movable must read apart across a whole column at a glance, so the
   two states differ in colour, in fill and in wording, not in glyph alone. */
.lock {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font: inherit;
  font-size: 0.78rem;
  line-height: 1;
  min-height: 1.75rem;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
}
.lock[data-fixed="true"] {
  border-color: var(--navy);
  background: var(--navy);
  color: #fff;
  font-weight: 600;
}
.lock:hover:not(:disabled) { border-color: var(--planned); color: var(--navy); }
.lock[data-fixed="true"]:hover:not(:disabled) { border-color: var(--navy); color: #fff; }
.lock:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.lock:disabled { cursor: default; opacity: 0.35; }
.lock.rule { cursor: default; border-style: dashed; }

/* Hover detail: when, which race, which hull on one line; the crew with their
   weights under it; when the boat is free again. Kept narrow so it covers as
   little of the chart as possible. Positioned from JavaScript. */
.tl-detail {
  position: absolute;
  z-index: 8;
  pointer-events: none;
  width: max-content;
  max-width: 17rem;
  padding: 0.4rem 0.6rem 0.45rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--navy);
  border-radius: var(--radius);
  box-shadow: var(--shadow-pop);
  font-size: 0.87rem;
  line-height: 1.3;
}
.tl-detail-head { display: flex; align-items: center; gap: 0.45rem; white-space: nowrap; }
.tl-detail-head strong { font-variant-numeric: tabular-nums; }
.tl-detail-code { color: var(--navy); font-weight: 700; }
.tl-detail-boat { color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
.tl-detail-head .lock-icon { width: 0.8rem; height: 0.8rem; color: var(--navy); flex: none; }
.tl-detail-head .gauge { margin-left: auto; }
.tl-detail-crew {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.1rem 0.8rem;
  align-items: center;
  margin: 0.3rem 0 0;
  padding-top: 0.3rem;
  border-top: 1px solid var(--rule);
}
.tl-detail-crew dt { margin: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-detail-crew dd { margin: 0; }
.tl-detail-crew .weight-chip { font-size: 0.8rem; padding: 0 0.3rem; }
.tl-detail-free { margin: 0.3rem 0 0; color: var(--muted); font-size: 0.82rem; }
.tl-detail-free[data-short="true"] { color: #a02525; font-weight: 600; }

/* The boat itself is the thing being held, so the state is on the row and on
   the dropdown too: reading down the column, the held ones are the navy ones. */
.boat-cell { display: flex; align-items: center; gap: 0.4rem; }
.fit-cell { width: 6.5rem; }
.fit-cell .gauge { display: block; }
.boat-cell select { flex: 1; min-width: 0; }
.boat-cell select[data-fixed="true"] {
  border: 1px solid var(--navy);
  border-left: 5px solid var(--navy);
  font-weight: 600;
}
#entries tr[data-fixed="true"] td:first-child {
  box-shadow: inset 3px 0 0 var(--navy);
}

@media (max-width: 1200px) {
  .lock-word { display: none; }
}

.legend {
  display: flex; align-items: center; gap: 0.4rem 1.2rem;
  font-size: 0.85rem; color: var(--muted); flex-wrap: wrap;
  margin: 0.7rem 0 0;
}
.legend-item { display: inline-flex; align-items: center; gap: 0.4rem; }
.key {
  width: 1.4rem; height: 0.7rem;
  border-radius: 3px;
  display: inline-block;
}
.key-pill { background: var(--planned); }
.key-block { background: var(--rest); }
.key-buffer {
  background: color-mix(in srgb, var(--rest) 42%, var(--paper));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rest) 55%, var(--paper));
}
.key-rest {
  height: 0.4rem;
  background: color-mix(in srgb, var(--navy) 30%, var(--paper));
}
.key-taken {
  background: repeating-linear-gradient(
    -45deg, var(--error) 0 3px,
    color-mix(in srgb, var(--error) 55%, var(--paper)) 3px 7px
  );
}
.key-eaten {
  background: repeating-linear-gradient(
    -45deg, var(--warn) 0 3px,
    color-mix(in srgb, var(--warn) 45%, var(--paper)) 3px 7px
  );
}
.key-fixed { background: var(--navy); }
.key-open { background: var(--paper); box-shadow: inset 0 0 0 2px var(--error); }
.key-heavy {
  width: auto; height: auto;
  color: var(--warn-ink);
  font-size: 0.85rem;
  line-height: 1;
}
.key-weights { display: inline-flex; width: auto; height: auto; gap: 2px; }
.key-weights span { width: 0.75rem; height: 0.75rem; border-radius: 2px; background: var(--w); }
.legend-hint { margin-left: auto; }

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 24rem;
  gap: 0 1.5rem;
  padding: 0.5rem 0 0;
  align-items: start;
}
.lede { color: var(--muted); font-size: 0.9rem; max-width: 46rem; margin: 0.9rem 0 0.4rem; }
@media (max-width: 82rem) { .split { grid-template-columns: 1fr; } }

table.grid {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 0.9rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: calc(var(--radius) + 3px);
}
table.grid th {
  text-align: left;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--muted);
  background: var(--surface);
  padding: 0.6rem 0.6rem 0.5rem;
  border-bottom: 1px solid var(--rule-strong);
  position: sticky;
  top: 3.6rem;
  z-index: 3;
  white-space: nowrap;
}
table.grid thead tr:first-child th:first-child { border-top-left-radius: calc(var(--radius) + 3px); }
table.grid thead tr:first-child th:last-child { border-top-right-radius: calc(var(--radius) + 3px); }
table.grid td { padding: 0.45rem 0.6rem; border-bottom: 1px solid var(--rule); }
table.grid tbody tr:last-child td { border-bottom: none; }
table.grid tbody tr:nth-child(even) { background: var(--row-alt); }
table.grid tbody tr[data-severity="error"] { box-shadow: inset 3px 0 0 var(--error); }
table.grid tbody tr[data-severity="warning"] { box-shadow: inset 3px 0 0 var(--warn); }
table.grid tbody tr[data-selected="true"] { background: var(--highlight); }
.num { font-variant-numeric: tabular-nums; }
.strong { font-weight: 700; }
.dim { color: var(--muted); }
.grid select {
  min-height: 1.95rem;
  padding: 0.2rem 1.7rem 0.2rem 0.5rem;
  font-size: 0.87rem;
  background-position: right 0.5rem center;
  max-width: 10rem;
}

.issues, .inbox { list-style: none; margin: 0 0 1.5rem; padding: 0; font-size: 0.88rem; }
.issues {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: calc(var(--radius) + 3px);
  overflow: hidden;
}
.issues li {
  padding: 0.6rem 0.8rem;
  border-left: 3px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  cursor: pointer;
}
.issues li:last-child { border-bottom: none; }
.issues li[data-severity="error"] { border-left-color: var(--error); }
.issues li[data-severity="warning"] { border-left-color: var(--warn); }
.issues li[data-severity="info"] { border-left-color: var(--info); color: var(--muted); }
.issues li:hover, .issues li:focus-visible { background: var(--navy-soft); outline: none; }

/* A weight note as a row: race, crew and boat, gauge, the two ratings. */
.issues li.issue-row {
  display: grid;
  grid-template-columns: 2.6rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.1rem 0.6rem;
}
.issue-code { font-weight: 700; color: var(--navy); font-variant-numeric: tabular-nums; }
.issue-who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.issue-fit { grid-column: 2 / -1; color: var(--muted); font-size: 0.85rem; }
.issue-fit .weight-chip { font-size: 0.82rem; }

/* Filter over the findings: one toggle per kind, the count coloured by the
   worst finding in it. */
.filter { display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0 0 0.6rem; }
.filter button {
  display: inline-flex; align-items: center; gap: 0.45rem;
  min-height: 2rem;
  background: var(--control);
  color: var(--ink);
  font-size: 0.87rem;
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
}
.filter button:hover { background: var(--control-hover); }
.filter button[aria-pressed="true"] { background: var(--navy); color: #fff; }
.filter-count {
  min-width: 1.5rem;
  padding: 0.05rem 0.35rem;
  border-radius: 999px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  background: var(--row-alt);
  color: var(--muted);
}
.filter button[data-worst="error"] .filter-count { background: var(--error); color: #fff; }
.filter button[data-worst="warning"] .filter-count { background: var(--warn); color: var(--ink); }
.filter button[data-worst="info"] .filter-count { background: var(--info); color: var(--ink); }

/* Weight gauge: five steps, the boat a ring, the crew a dot. */
.gauge { flex: none; overflow: visible; vertical-align: middle; }
.gauge-axis { stroke: var(--rule); stroke-width: 1.5; }
.gauge-tick { fill: var(--w, var(--locked)); }
.gauge-boat { fill: none; stroke: var(--navy); stroke-width: 2; }
.gauge-crew { fill: var(--good); }
.gauge-span { stroke-width: 3; stroke: var(--locked); }
.gauge[data-verdict="heavy"] .gauge-crew { fill: var(--warn); }
.gauge[data-verdict="heavy"] .gauge-span { stroke: var(--warn); }
.gauge[data-verdict="light"] .gauge-crew { fill: var(--locked); }
.inbox li {
  padding: 0.35rem 0.6rem;
  border-bottom: 1px solid var(--rule);
  color: var(--muted);
  display: flex; justify-content: space-between; gap: 0.5rem;
}
.empty { color: var(--muted); padding: 0.5rem 0.6rem; }


/* Shared controls inside editable tables. Kept plain: the row is the object, and
   a box around every field would turn a dense table into a wall of chrome. */
.grid input[type="text"], .grid input[type="number"], .grid input[type="date"],
.grid input[type="time"] {
  font: inherit;
  font-size: 0.88rem;
  padding: 0.15rem 0.3rem;
  border: 1px solid transparent;
  border-bottom: 1px solid var(--rule);
  border-radius: 0;
  background: transparent;
  width: 100%;
  min-width: 3rem;
  color: inherit;
}
.grid input:hover { border-bottom-color: var(--navy); }
.grid input:focus { outline: none; border: 1px solid var(--focus); background: #fff; }
.grid input[type="checkbox"] { width: 1rem; height: 1rem; accent-color: var(--navy); }
.grid td.narrow { width: 5rem; }
.grid td.tiny { width: 3.5rem; }
.grid td.middle { text-align: center; }
.grid .seats { display: flex; gap: 0.25rem; flex-wrap: wrap; }
.grid .seats select { max-width: 8rem; }
.grid tr.adder td { background: var(--navy-soft); }
.remove {
  border: none; background: transparent; color: var(--muted);
  font-size: 1rem; line-height: 1; padding: 0.2rem 0.4rem; cursor: pointer;
}
.remove:hover { color: var(--error); }
td.off-home { box-shadow: inset 0 -3px 0 var(--warn); }
.in-use {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.8rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.in-use[data-off="true"] { color: var(--warn-ink); font-weight: 600; }

/* An interpolated start: shown, but plainly not a fact yet. */
.estimated, .estimated input { color: var(--muted); font-style: italic; }
.block-span { display: block; font-size: 0.85rem; }
.placed input { text-decoration: underline dotted var(--slalom-ink); text-underline-offset: 3px; }

/* Starts per day as short bars; one line per day. */
.day-bars { font-size: 0.82rem; }
.day-bar {
  display: grid;
  grid-template-columns: 1.9rem 1fr 1.4rem;
  align-items: center;
  gap: 0.4rem;
  line-height: 1.35;
}
.day-bar-label { color: var(--muted); }
.day-bar-track { height: 0.5rem; background: color-mix(in srgb, var(--rule) 55%, var(--paper)); border-radius: 2px; overflow: hidden; }
.day-bar-fill { display: block; height: 100%; background: var(--navy); }
.day-bar-count { text-align: right; }
.day-bar[data-empty="true"] .day-bar-count { color: var(--muted); }

.current-boat { display: flex; align-items: center; justify-content: space-between; gap: 0.4rem; }
.current-boat span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* A pause of three quarters of an hour or more, and a change of day, drawn as
   a rule, as on the printout. */
#entries tr[data-gap="true"] td { border-top: 2px solid var(--navy); }
#meldungen tr[data-new-day="true"] td { border-top: 3px solid var(--navy); }


/* The Stammboot grid has few, narrow columns. Left at full width the controls
   drift apart and the eye loses the row. Boat-class codes are literals, so the
   uppercasing used for ordinary column labels must not touch them. */
#stammboote-table { width: auto; min-width: 34rem; }
#stammboote-table th:first-child, #stammboote-table td:first-child { min-width: 9rem; }
#stammboote-table th + th { text-transform: none; letter-spacing: 0; font-size: 0.8rem; }
#stammboote-table td + td { width: 9.5rem; }
#stammboote-table select { width: 100%; max-width: 9rem; }


/* Busy marker. A static rule and a word: the interface stays fully usable while
   the server catches up, so nothing here disables or animates anything. */
body[data-busy="true"] .toolbar { border-bottom-color: var(--warn); }
body[data-busy="true"] #working { display: inline; }
#working { display: none; color: var(--warn-ink); font-weight: 700; margin-left: 0.6rem; }
.auto-repair {
  display: flex; align-items: center; gap: 0.35rem;
  font-size: 0.85rem; color: var(--muted); white-space: nowrap;
}
.auto-repair input { width: 1rem; height: 1rem; accent-color: var(--navy); }


/* Record tables are laid out to a fixed width per column rather than stretched
   to the window. A full-width table puts a rower's name a thousand pixels from
   the control that changes them, and the row stops reading as one thing. Fixed
   layout also stops a long boat name from shoving every later column sideways. */
table.records {
  table-layout: fixed;
  width: auto;
  max-width: 100%;
}
table.records th, table.records td {
  overflow: hidden;
  text-overflow: ellipsis;
}

#athletes-table { width: 57rem; }
#athletes-table th:nth-child(1) { width: 14rem; }
#athletes-table th:nth-child(2) { width: 9rem; }
#athletes-table th:nth-child(3) { width: 6rem; }
#athletes-table th:nth-child(4) { width: 14rem; }
#athletes-table th:nth-child(5) { width: 11rem; }
#athletes-table th:nth-child(6) { width: 3rem; }

#boats-table { width: 64rem; }
#boats-table th:nth-child(1) { width: 14rem; }
#boats-table th:nth-child(2) { width: 5rem; }
#boats-table th:nth-child(3) { width: 9rem; }
#boats-table th:nth-child(4) { width: 7.5rem; }
#boats-table th:nth-child(5) { width: 12rem; }
#boats-table th:nth-child(6) { width: 13.5rem; }
#boats-table th:nth-child(7) { width: 3rem; }

#races-table { width: 68rem; }
#races-table th:nth-child(1) { width: 5rem; }
#races-table th:nth-child(2) { width: 17rem; }
#races-table th:nth-child(3) { width: 5.5rem; }
#races-table th:nth-child(4) { width: 8rem; }
#races-table th:nth-child(5) { width: 7rem; }
#races-table th:nth-child(6) { width: 5.5rem; }
#races-table th:nth-child(7) { width: 10rem; }
#races-table th:nth-child(8) { width: 7rem; }
#races-table th:nth-child(9) { width: 3rem; }

#meldungen-table { width: 88rem; }
#meldungen-table th:nth-child(1) { width: 8rem; }
#meldungen-table th:nth-child(2) { width: 8rem; }
#meldungen-table th:nth-child(3) { width: 24rem; }
#meldungen-table th:nth-child(4) { width: 5.5rem; }
#meldungen-table th:nth-child(5) { width: 9rem; }
#meldungen-table th:nth-child(6) { width: 5.5rem; }
#meldungen-table th:nth-child(7) { width: 10rem; }
#meldungen-table th:nth-child(8) { width: 14rem; }
#meldungen-table th:nth-child(9) { width: 3rem; }

/* The day table has content in every column, so it may use the width it is
   given, but not more than the eye can track across. */
#entries-table { max-width: 72rem; }


/* Tracking a row across several controls is the whole job on these screens, so
   the row under the pointer is marked. Focus inside a row counts as well, for
   anyone working through with the keyboard. */
table.grid tbody tr:hover,
table.grid tbody tr:focus-within { background: var(--navy-soft); }
table.grid tbody tr.adder:hover { background: var(--highlight); }

/* ==== hosted app: shell, lists, sharing, account, phone ===================
   The same colours answer the same questions here as on the planning desk:
   navy held by hand, blue chosen by the solver, red missing or wrong, orange
   worth a look, brown for weighing, class colours for boat classes. */

[hidden] { display: none !important; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.screen { padding: 0 1.5rem 3rem; }
#screen-home, #screen-account, #screen-share { max-width: 76rem; margin: 0 auto; }
#screen-plan { padding: 0; }
.muted { color: var(--muted); }
td.strong, .strong { font-weight: 600; }

/* ---- header ---- */
.brand {
  display: inline-flex; align-items: center; gap: 0.55rem;
  color: var(--ink); text-decoration: none;
  font-weight: 700; font-size: 1.02rem; letter-spacing: -0.01em;
  border-radius: var(--radius);
}
.brand-mark { width: 2rem; height: 2rem; border-radius: 8px; }
.bar-end { margin-left: auto; display: flex; align-items: center; gap: 0.35rem; }
.bar-link {
  display: inline-flex; align-items: center;
  min-height: 2.1rem; padding: 0.35rem 0.8rem;
  color: var(--muted); font-weight: 600; font-size: 0.9rem;
  text-decoration: none; border-radius: 999px;
}
.bar-link:hover { background: var(--control); color: var(--ink); }
body[data-screen="account"] #nav-account,
body[data-screen="share"] #nav-share { background: var(--navy-soft); color: var(--navy); }
#user-button { display: inline-flex; min-width: 2.1rem; min-height: 2.1rem; align-items: center; margin-left: 0.4rem; }
.link-line {
  font-size: 0.85rem; font-weight: 600;
  padding: 0.3rem 0.7rem; border-radius: 999px;
  background: var(--warn-soft); color: var(--warn-ink);
}
.link-line[data-tone="off"] { background: var(--error-soft); color: #9c2323; }
.status:has(#status-text:empty) { display: none; }
body:not([data-screen="plan"]) .status { max-width: 76rem; margin: 1rem auto 0; border-radius: var(--radius); }

/* Viewers see the plan but not the tools that change it. */
body[data-readonly="true"] .edit-only,
body[data-readonly="true"] tr.adder,
body[data-readonly="true"] .adder { display: none !important; }
body[data-readonly="true"] .grid input:disabled,
body[data-readonly="true"] .grid select:disabled {
  color: var(--ink); opacity: 1; background-color: transparent; border-color: transparent;
  background-image: none;
}

/* ---- sign-in ---- */
.signin { display: flex; flex-direction: column; align-items: center; padding-top: 4rem; }
.signin-note {
  width: min(26rem, 100%);
  color: var(--warn-ink); background: var(--warn-soft);
  padding: 0.6rem 0.8rem; border-radius: var(--radius);
}
.signin-form { width: min(26rem, 100%); min-height: 18rem; }
.dev-signin { display: flex; flex-direction: column; gap: 0.8rem; }
.dev-signin label { display: flex; flex-direction: column; gap: 0.35rem; font-weight: 600; }

/* ---- regatta list ---- */
table.projects { margin-top: 1.6rem; font-size: 0.95rem; }
table.projects td { padding: 0.95rem 0.8rem; vertical-align: middle; }
table.projects th { padding-left: 0.8rem; }
table.projects tbody tr { cursor: pointer; }
table.projects tbody tr:nth-child(even) { background: var(--surface); }
.project-name a { font-weight: 700; font-size: 1.05rem; color: var(--ink); text-decoration: none; }
.project-name a::after { content: ""; }
table.projects tbody tr:hover .project-name a { color: var(--navy); text-decoration: underline; text-underline-offset: 3px; }
.project-venue { display: block; color: var(--muted); font-size: 0.88rem; margin-top: 0.1rem; }
.project-days, .project-squad { white-space: nowrap; color: var(--ink); font-variant-numeric: tabular-nums; }
.project-role { color: var(--muted); font-weight: 600; font-size: 0.88rem; }
.project-role[data-role="owner"] { color: var(--navy); }

.coverage { display: flex; flex-direction: column; gap: 0.35rem; min-width: 14rem; }
.coverage-bar {
  display: flex; gap: 2px; height: 0.6rem; border-radius: 999px; overflow: hidden;
  background: var(--control);
}
.coverage-bar span { display: block; min-width: 4px; }
.coverage-fixed { background: var(--navy); }
.coverage-solved { background: var(--planned); }
.coverage-missing { background: var(--error); }
.coverage-words { font-size: 0.87rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.coverage-legend { display: flex; gap: 0.4rem 1.4rem; flex-wrap: wrap; font-size: 0.87rem; color: var(--muted); margin: 0.8rem 0.2rem 0; }
.coverage-legend > span { display: inline-flex; align-items: center; gap: 0.45rem; }
.swatch { display: inline-block; width: 0.8rem; height: 0.8rem; border-radius: 3px; }

.findings { white-space: nowrap; }
.findings span {
  display: inline-block; padding: 0.15rem 0.55rem; border-radius: 999px;
  font-size: 0.85rem; font-weight: 600;
}
.findings span + span { margin-left: 0.35rem; }
.finding-error { color: #a02525; background: var(--error-soft); }
.finding-warning { color: var(--warn-ink); background: var(--warn-soft); }
.finding-ok { color: var(--good-ink); background: #e5f4e5; }

.project-adder, .invite, .key-adder, .rename {
  display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center;
  margin-top: 1.4rem;
}
.project-adder input[type="text"], .invite input, .key-adder input, .rename input { min-width: 17rem; }
.project-adder select, .key-adder select { max-width: 20rem; }

/* ---- sharing ---- */
.back-link {
  display: inline-flex; align-items: center; gap: 0.3rem;
  margin: 1.2rem 0 0.8rem; color: var(--muted); font-weight: 600; text-decoration: none;
}
.back-link:hover { color: var(--navy); }
table.members td { padding: 0.7rem 0.8rem; }
.member-joined { color: var(--good-ink); }
.member-invited { color: var(--warn-ink); }
select[data-role="owner"], .role-chip[data-role="owner"] { box-shadow: inset 4px 0 0 var(--navy); }
select[data-role="editor"], .role-chip[data-role="editor"] { box-shadow: inset 4px 0 0 var(--planned); }
select[data-role="viewer"], .role-chip[data-role="viewer"] { box-shadow: inset 4px 0 0 var(--w1); }
.role-chip { display: inline-block; padding: 0.2rem 0.6rem 0.2rem 0.8rem; background: var(--control); border-radius: var(--radius); }
.rename { padding-top: 1.4rem; border-top: 1px solid var(--rule); }
.rename label { display: inline-flex; align-items: center; gap: 0.6rem; font-weight: 600; }
.danger { margin-top: 2.4rem; padding-top: 1.2rem; border-top: 1px solid var(--rule); }
button.danger-button { background: var(--error-soft); color: #a02525; }
button.danger-button:hover { background: #f6d6d4; }

/* ---- account: calendars ---- */
#screen-account > table.grid { margin-top: 1.6rem; }
table.calendars td, table.keys td { padding: 0.7rem 0.7rem; vertical-align: middle; }
.subscribe { white-space: nowrap; }
.subscribe a {
  display: inline-flex; align-items: center; min-height: 2rem; padding: 0.3rem 0.7rem;
  margin-right: 0.3rem; border-radius: var(--radius);
  background: var(--navy-soft); color: var(--navy); font-weight: 600; text-decoration: none; font-size: 0.88rem;
}
.subscribe a:hover { background: #dde7f2; }
.row-actions { white-space: nowrap; text-align: right; }
.row-actions button, .subscribe button { min-height: 2rem; padding: 0.3rem 0.65rem; font-size: 0.86rem; }
.row-actions button + button { margin-left: 0.25rem; }
.section-action { margin-top: 1rem; }

.calendar-editor {
  margin-top: 1.2rem; padding: 1.2rem 0 1.4rem 1.4rem;
  border-left: 3px solid var(--planned);
  display: flex; flex-direction: column; gap: 1.2rem;
}
.editor-row { display: flex; flex-wrap: wrap; gap: 0.9rem 1.8rem; align-items: center; }
.editor-row label, .editor-title label { display: inline-flex; align-items: center; gap: 0.55rem; font-weight: 600; }
.editor-row input[type="text"], .editor-title input { font-weight: 400; min-width: 18rem; }
.editor-row input[type="number"] { width: 5rem; }
.segmented-label { align-self: center; font-weight: 600; margin: 0 0.5rem 0 0.4rem; color: var(--ink); }
.editor-filters { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 1.2rem 2.4rem; }
.checklist { border: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.35rem; }
.checklist legend { font-weight: 600; margin-bottom: 0.5rem; padding: 0; width: 100%; }
.check {
  display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 400;
  padding: 0.3rem 0.65rem 0.3rem 0.5rem; border-radius: 999px; background: var(--control);
  cursor: pointer; font-size: 0.9rem;
}
.check:hover { background: var(--control-hover); }
.check:has(input:checked) { background: var(--navy-soft); color: var(--navy); font-weight: 600; box-shadow: inset 0 0 0 1px #c3d3e6; }
.check.all { font-weight: 600; }
.checklist .class-chip { min-width: 0; margin-left: 0.1rem; }
.checklist.inline .check { background: transparent; padding-left: 0; }
.checklist.inline .check:has(input:checked) { background: transparent; box-shadow: none; color: var(--ink); font-weight: 400; }
.editor-title { display: flex; flex-direction: column; gap: 0.6rem; }
.editor-title input { min-width: min(34rem, 100%); }
.placeholder-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center; }
button.chip-button {
  min-height: 1.85rem; padding: 0.2rem 0.65rem; font-size: 0.86rem; font-weight: 600;
  background: var(--surface); color: var(--navy); border: 1px dashed #b6c6d8; border-radius: 999px;
}
button.chip-button:hover { background: var(--navy-soft); }
.weigh-toggle input { accent-color: var(--w4); }
.weigh-toggle:has(input:checked) { background: color-mix(in srgb, var(--w2) 20%, #fff); color: var(--w5); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--w2) 45%, #fff); }
.editor-actions { display: flex; gap: 0.6rem; }

.calendar-preview {
  padding: 1rem 1.1rem 0.4rem;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: calc(var(--radius) + 3px);
}
.preview-lede { margin: 0 0 0.8rem; font-weight: 700; }
.preview-error { color: #a02525; }
.preview-day { display: grid; grid-template-columns: 6.5rem minmax(0, 1fr); gap: 0.3rem 1rem; margin-bottom: 1.2rem; }
.preview-daylabel { grid-row: span 3; font-weight: 700; color: var(--navy); }
.preview-axis { position: relative; height: 1.3rem; border-bottom: 1px solid var(--rule); }
.preview-hour { position: absolute; transform: translateX(-50%); font-size: 0.85rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.preview-track { position: relative; margin-top: 0.3rem; }
.preview-bar { position: absolute; height: 10px; border-radius: 999px; background: var(--planned); }
.preview-bar.kind-weigh { background: var(--w2); }
.preview-list { list-style: none; margin: 0.5rem 0 0; padding: 0; columns: 2 22rem; column-gap: 2rem; }
.preview-list li { break-inside: avoid; padding: 0.2rem 0; display: flex; gap: 0.7rem; }
.preview-list li.kind-weigh { color: var(--w4); }
.preview-time { font-variant-numeric: tabular-nums; color: var(--muted); white-space: nowrap; }

/* ---- account: keys ---- */
.key-prefix { font-size: 0.86rem; color: var(--muted); }
td[data-scope="write"] { color: var(--navy); font-weight: 600; }
.revealed {
  margin-top: 1.2rem; padding: 0.9rem 1.1rem;
  background: #fff8db; border: 1px solid #f1dd8c; border-radius: calc(var(--radius) + 3px);
}
.reveal-note { margin: 0 0 0.6rem; font-weight: 700; color: #6a4b00; }
.reveal-row { display: grid; grid-template-columns: 10rem minmax(0, 1fr) auto; gap: 0.7rem; align-items: start; padding: 0.5rem 0; border-top: 1px solid #f1dd8c; }
.reveal-label { font-weight: 600; padding-top: 0.45rem; }
.reveal-row pre {
  margin: 0; padding: 0.45rem 0.6rem; background: #fffdf2; border-radius: var(--radius);
  font-size: 0.87rem; white-space: pre-wrap; word-break: break-all;
}

/* ---- phone view ---- */
.mobile { padding: 0 1rem 2.5rem; }
.m-controls {
  position: sticky; top: 3.6rem; z-index: 10;
  display: flex; flex-direction: column; gap: 0.6rem;
  margin: 0 -1rem; padding: 0.8rem 1rem 0.7rem;
  background: rgb(245 247 250 / 94%); backdrop-filter: blur(8px);
}
.m-days { display: flex; gap: 3px; padding: 3px; border-radius: 12px; background: var(--control); }
.m-days button {
  flex: 1; min-height: 2.5rem; font-size: 1rem;
  background: transparent; color: var(--muted); border-radius: 9px;
}
.m-days button[aria-pressed="true"] { background: var(--surface); color: var(--navy); box-shadow: 0 1px 3px rgb(23 33 44 / 14%); }
.mobile .m-filter { font-size: 1rem; min-height: 2.6rem; width: 100%; border-radius: 10px; }
.m-strip-wrap {
  position: relative; margin: 0.4rem 0 1rem; padding: 0.6rem 0.7rem 1.6rem;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 12px;
}
.m-strip { width: 100%; height: 4rem; display: block; }
.m-strip-axis { stroke: #b8c2cd; stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.m-strip-tick { stroke: #b8c2cd; stroke-width: 1; vector-effect: non-scaling-stroke; }
.m-strip-run { fill: var(--seat, var(--planned)); }
.m-strip-run.open { fill: var(--slalom); stroke: var(--slalom-ink); stroke-width: 1; vector-effect: non-scaling-stroke; }
.m-strip-now { stroke: var(--highlight-edge); stroke-width: 2.5; vector-effect: non-scaling-stroke; }
.m-strip-hours { position: absolute; left: 0.7rem; right: 0.7rem; bottom: 0.35rem; height: 1rem; }
.m-strip-hours span { position: absolute; transform: translateX(-50%); font-size: 0.85rem; color: var(--muted); }
.m-strip-hours span:first-child { transform: none; }
.m-strip-hours span:last-child { transform: translateX(-100%); }
.m-list {
  list-style: none; margin: 0; padding: 0;
  background: var(--surface); border: 1px solid var(--rule); border-radius: 12px; overflow: hidden;
}
.m-row {
  display: grid; grid-template-columns: 4.4rem minmax(0, 1fr); gap: 0.8rem;
  padding: 0.85rem 0.9rem 0.85rem 0.75rem;
  border-bottom: 1px solid var(--rule);
  box-shadow: inset 4px 0 0 var(--seat, var(--rule));
}
.m-row:last-child { border-bottom: none; }
.m-row[data-next="true"] { background: #fff8db; }
.m-row[data-past="true"] { color: #6b7580; background: var(--canvas); }
.m-row[data-past="true"] .m-start { color: #6b7580; }
.m-time { display: flex; flex-direction: column; padding-left: 0.2rem; }
.m-start { font-size: 1.35rem; font-weight: 700; color: var(--navy); font-variant-numeric: tabular-nums; line-height: 1.1; letter-spacing: -0.01em; }
.m-launch { font-size: 0.9rem; color: var(--muted); font-variant-numeric: tabular-nums; margin-top: 0.1rem; }
.m-body { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.m-boat { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; }
.m-boat-name { font-size: 1.1rem; font-weight: 700; }
.m-boat-name.missing { color: #a02525; }
.m-next { font-size: 0.85rem; font-weight: 700; color: #6a4b00; background: #ffe28a; padding: 0.05rem 0.5rem; border-radius: 999px; }
.m-crew { font-size: 1rem; }
.m-race { display: flex; gap: 0.4rem; align-items: center; flex-wrap: wrap; font-size: 0.92rem; color: var(--muted); }
.m-race-nr { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; }
.m-meta { font-size: 0.9rem; color: var(--muted); }
.m-weigh { font-size: 0.92rem; font-weight: 600; color: var(--w4); }
.m-empty, .m-undated { color: var(--muted); padding: 1rem 0.2rem; }
.m-foot { color: var(--muted); font-size: 0.88rem; margin-top: 1rem; text-align: center; }

@media (max-width: 760px) {
  .bar { padding: 0.45rem 1rem; gap: 0.2rem 0.6rem; min-height: 3.4rem; flex-wrap: wrap; }
  .bar h1 { order: 3; flex-basis: 100%; max-width: none; padding: 0 0 0.25rem; border-left: none; font-size: 1rem; }
  body[data-screen="mobile"] .brand-text, body[data-screen="share"] .brand-text { display: none; }
  .bar-link { padding: 0.35rem 0.6rem; }
  .views, .toolbar { display: none !important; }
  .m-controls { top: 5.4rem; }
  .screen { padding: 0 1rem 2.5rem; }
  .project-adder { display: none; }
  table.grid th { top: 3.4rem; }
  table.projects thead { display: none; }
  table.projects tr { display: grid; grid-template-columns: 1fr auto; padding: 0.8rem 0.9rem; border-bottom: 1px solid var(--rule); }
  table.projects tbody tr:last-child { border-bottom: none; }
  table.projects td { padding: 0.15rem 0; border: none; }
  table.projects td.project-name { grid-column: 1 / -1; }
  table.projects td:has(.coverage) { grid-column: 1 / -1; padding: 0.5rem 0; }
  table.projects .project-squad { display: none; }
  .signin { padding-top: 1.5rem; }
  table.calendars thead, table.keys thead, table.members thead { display: none; }
  table.calendars tr, table.keys tr, table.members tr { display: flex; flex-wrap: wrap; gap: 0.3rem 0.8rem; padding: 0.8rem 0.9rem; border-bottom: 1px solid var(--rule); }
  table.calendars td, table.keys td, table.members td { border: none; padding: 0.1rem 0; }
  .subscribe { white-space: normal; display: flex; flex-wrap: wrap; gap: 0.4rem; width: 100%; }
  .row-actions { text-align: left; }
  .editor-row input[type="text"], .editor-title input { min-width: 0; width: 100%; }
  .editor-row label { flex-wrap: wrap; }
  .calendar-editor { padding-left: 0.9rem; }
  .preview-day { grid-template-columns: 1fr; }
  .preview-daylabel { grid-row: auto; }
  .reveal-row { grid-template-columns: 1fr; }
  .key-adder input, .invite input, .rename input { min-width: 0; flex: 1 1 100%; }
}


/* ==== plan desk: tabs, toolbar, feedback on the controls ==================== */

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.icon { width: 1.05rem; height: 1.05rem; flex: none; }

/* The regatta's own row: its views as underlined tabs, set apart from the
   header's account links by shape as well as by place. */
.tabs {
  display: flex;
  align-items: flex-end;
  gap: 1.2rem;
  padding: 0 1.5rem;
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
}
.tabs .views { gap: 0.2rem; }
.tabs .views button {
  min-height: 2.75rem;
  padding: 0.55rem 0.85rem 0.6rem;
  border-radius: 0;
  background: transparent;
  color: var(--muted);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 transparent;
}
.tabs .views button:hover { color: var(--ink); background: transparent; box-shadow: inset 0 -2px 0 var(--rule-strong); }
.tabs .views button[aria-current="true"] {
  color: var(--navy);
  background: transparent;
  box-shadow: inset 0 -3px 0 var(--navy);
}
.plan-summary {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem 0.9rem;
  margin: 0 0 0 auto; padding: 0.6rem 0;
  font-size: 0.88rem; color: var(--ink); font-variant-numeric: tabular-nums;
}
.plan-summary [data-tone="error"] { color: #a02525; font-weight: 700; }
.plan-summary [data-tone="warn"] { color: var(--warn-ink); font-weight: 600; }
.plan-summary [data-tone="fixed"] { color: var(--navy); font-weight: 600; }
.plan-summary [data-tone="muted"] { color: var(--muted); }
.tab-link {
  display: inline-flex; align-items: center; gap: 0.4rem;
  margin: 0 0 0.45rem; padding: 0.4rem 0.8rem; border-radius: 999px;
  background: var(--navy-soft); color: var(--navy); font-weight: 600; font-size: 0.9rem;
  text-decoration: none;
}
.tab-link:hover { background: #dde7f2; }

/* Toolbar: the one filled button is the action that matters; the lock pair is
   one control; documents on the right are plain text buttons. */
.toolbar .tools { gap: 0.55rem; }
button.ghost, .button.ghost { background: transparent; color: var(--ink); }
button.ghost:hover, .button.ghost:hover { background: var(--control); }
.joined { display: inline-flex; }
.joined button { border-radius: 0; }
.joined button:first-child { border-radius: var(--radius) 0 0 var(--radius); }
.joined button:last-child { border-radius: 0 var(--radius) var(--radius) 0; box-shadow: inset 1px 0 0 var(--rule-strong); }

.switch { display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer; font-size: 0.9rem; color: var(--ink); }
.switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.switch-track {
  position: relative; width: 2.1rem; height: 1.2rem; flex: none;
  border-radius: 999px; background: var(--rule-strong); transition: background-color 150ms ease;
}
.switch-track::after {
  content: ""; position: absolute; top: 0.15rem; left: 0.15rem;
  width: 0.9rem; height: 0.9rem; border-radius: 50%; background: #fff;
  box-shadow: 0 1px 2px rgb(23 33 44 / 25%); transition: transform 150ms ease;
}
.switch input:checked + .switch-track { background: var(--good-ink); }
.switch input:checked + .switch-track::after { transform: translateX(0.9rem); }
.switch input:focus-visible + .switch-track { box-shadow: var(--ring); }
.switch-label { min-width: 7.5rem; }
.switch-label[data-outcome="good"] { color: var(--good-ink); font-weight: 600; }
.switch-label[data-outcome="error"] { color: #a02525; font-weight: 600; }
.switch-label[data-outcome="busy"] { color: var(--muted); }

/* An outcome shown on the button that caused it. The button keeps its width;
   its label is covered by the note until the note times out. */
button[data-note], .button[data-note] { position: relative; color: transparent !important; }
button[data-note] > *, .button[data-note] > * { visibility: hidden; }
button[data-note]::after, .button[data-note]::after {
  content: attr(data-note);
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 0 0.6rem; white-space: nowrap;
  border-radius: inherit;
  font-weight: 600;
}
[data-outcome="good"][data-note]::after { background: #e3f3e3; color: var(--good-ink); }
[data-outcome="error"][data-note]::after { background: var(--error-soft); color: #a02525; }
[data-outcome="busy"][data-note]::after { background: var(--control); color: var(--muted); }
[data-outcome="plain"][data-note]::after { background: var(--control); color: var(--ink); }
button[data-outcome="busy"] { pointer-events: none; }

/* A field that was just saved, or refused. */
input[data-mark="saved"], select[data-mark="saved"] {
  border-color: var(--good) !important;
  box-shadow: 0 0 0 3px rgb(12 163 12 / 18%);
}
input[data-mark="failed"], select[data-mark="failed"] {
  border-color: var(--error) !important;
  box-shadow: 0 0 0 3px rgb(208 59 59 / 20%);
}

/* The findings stay in view while the table scrolls past them. */
.side {
  position: sticky;
  top: 4.4rem;
  max-height: calc(100vh - 5.4rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.side .filter { position: sticky; top: 0; z-index: 2; padding: 0 0 0.6rem; margin: 0; background: var(--canvas); }
.issues li { border-left-width: 3px; }

/* The day table is the densest table in the app; its cells stay tight so it
   fits beside the findings. */
#entries-table td { padding: 0.35rem 0.45rem; }
#entries-table th { padding: 0.55rem 0.45rem 0.45rem; }
#entries-table .boat-cell select { max-width: 8.5rem; }

/* Calendar list and editor. */
.calendar-name { max-width: 16rem; }
.calendar-name span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.calendar-name .muted { font-size: 0.86rem; }
.subscribe { white-space: normal; }
.subscribe a, .subscribe button { margin: 0.15rem 0.3rem 0.15rem 0; }
.row-actions { white-space: normal; }
.editor-narrow { display: flex; flex-direction: column; gap: 1rem; }
.editor-row select, .key-adder select, .project-adder select { max-width: 100%; }
.editor-row label { max-width: 100%; }
.editor-row label select { min-width: 0; }

@media (max-width: 760px) {
  .tabs, .toolbar { display: none !important; }
}
