/* ==========================================================================
   DASHBOARD LAYER

   Loaded last, so it settles disagreements between main.css, components.css
   and admin.css without any of them having to be unpicked. Those three grew a
   control at a time — a filter here, a toolbar there — and the cost shows as
   six different input heights and four different label styles on one screen.

   This file does three things and nothing else:
     1. one control system: every input, select and button on one baseline
     2. one filter rail: the scattered per-panel filter boxes in a single bar
     3. one auth card: the staff sign-in, the first-run setup and the members
        sign-in all built from the same parts

   IT RENAMES NOTHING. Every id in admin.html is wired to admin.js — 192 of
   them — so this restyles and regroups around the existing markup rather than
   replacing it.
   ========================================================================== */

/* --------------------------------------------------------------------------
   TYPE

   IBM Plex Sans and Mono replace Outfit / Space Grotesk. Not fashion: Plex Sans
   has true tabular lining figures, so a yen column and a mileage column line up
   on the decimal without per-cell hacks, and Plex Mono shares the same
   skeleton — so a chassis code (S15, FD3S) or a lot number sits inside a sans
   table without looking pasted in from another document. Mono is used for
   codes, which ARE codes, and never as decoration on a label.
   -------------------------------------------------------------------------- */
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;450;500;600;700&display=swap');

:root {
  --font-main: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-heading: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* One control height, one radius, one gap. Every deviation below is a bug. */
  --ctl-h: 34px;
  --ctl-r: 6px;
  --ctl-pad: 0 10px;
  --rail-gap: 8px;


  /* Numerals line up in columns without being re-specified per table. */
  font-variant-numeric: tabular-nums;
}

body,
.admin-content,
.member-main {
  font-feature-settings: 'tnum' 1, 'lnum' 1;
}

/* --------------------------------------------------------------------------
   CONTROLS

   Six input heights became one. The selector list is explicit rather than a
   blanket `input, select` so that checkboxes and radios keep their native
   sizing — a checkbox stretched to 34px is how "aligned" turns into "wrong".
   -------------------------------------------------------------------------- */
.filter-input,
.admin-input,
input[type="text"].filter-input,
input[type="search"],
.auction-cookie-field input[type="text"],
.auction-cookie-field input[type="password"],
.admin-gate-box input,
.member-field input,
.member-field select,
select.filter-input {
  height: var(--ctl-h);
  padding: var(--ctl-pad);
  border: 1px solid var(--border-subtle);
  border-radius: var(--ctl-r);
  background: var(--bg-surface);
  color: var(--text-primary);
  font-family: var(--font-main);
  font-size: 0.875rem;
  line-height: calc(var(--ctl-h) - 2px);
  box-shadow: none;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

select.filter-input,
.member-field select {
  /* Room for the native arrow, so the longest option never collides with it. */
  padding-right: 26px;
}

.filter-input:hover,
.admin-input:hover,
.admin-gate-box input:hover,
.member-field input:hover {
  border-color: var(--border-strong);
}

.filter-input:focus,
.admin-input:focus,
.admin-gate-box input:focus,
.member-field input:focus,
.member-field select:focus,
.auction-cookie-field input:focus,
.auction-cookie-field textarea:focus {
  outline: none;
  border-color: var(--border-focus);
  /* A ring rather than a glow: it survives on a white panel and on an inset
     one, and it does not bloom into neighbouring controls in a dense rail. */
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.16);
}

/* Keyboard focus must stay obvious even where a mouse focus ring is subdued. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 2px;
}

.header-btn {
  height: var(--ctl-h);
  padding: 0 14px;
  border-radius: var(--ctl-r);
  font-family: var(--font-main);
  font-size: 0.85rem;
  font-weight: 500;
  line-height: calc(var(--ctl-h) - 2px);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   THE FILTER RAIL

   Every view had its own bar: inventory carried a search box and four selects,
   auctions carried a search box, five selects and three checkbox toggles, and
   each was styled slightly differently. One rail, one row, one set of rules.

   Grouping is by what a question is about, not by control type: what to show,
   then how to narrow it, then how to order it. Dividers mark those groups so
   the eye can skip to the right third of the rail instead of reading all nine
   controls.
   -------------------------------------------------------------------------- */
.filter-rail {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--rail-gap);
  padding: 10px 12px;
  margin-bottom: 14px;
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md, 10px);
}

/* A label sits with its control rather than above it: the rail is one line
   tall, and stacked labels would double its height for no added meaning. The
   control's own text carries the meaning; this is for the ones where it
   cannot (a bare select of grades needs to say "grade"). */
.filter-rail .rail-field {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.filter-rail .rail-label {
  font-size: 0.76rem;
  font-weight: 500;
  color: var(--text-secondary);
  white-space: nowrap;
}

/* The search box earns the space it takes; it is the control most used — but
   not at the cost of pushing "More filters" onto a second line. It gives ground
   before the rail wraps. */
.filter-rail .rail-search {
  flex: 1 1 180px;
  min-width: 120px;
  max-width: 360px;
}

/* KEEP THE RAIL ON ONE LINE.
   A select's default minimum width is its content, so three of them plus the
   search box would not fit and the end of the rail — the count and More
   filters — wrapped underneath. Letting the controls shrink keeps everything
   on one line at any normal window width; below that the rail still wraps,
   which is right on a phone. */
.filter-rail .rail-field { min-width: 0; }
.filter-rail .rail-field select.filter-input {
  min-width: 0;
  flex: 1 1 auto;
  max-width: 190px;
}
.filter-rail .rail-end { flex: 0 0 auto; }

.filter-rail .rail-divider {
  width: 1px;
  align-self: stretch;
  margin: 2px 4px;
  background: var(--border-subtle);
}

/* Pushes counts and actions to the far end, away from the inputs. */
.filter-rail .rail-end {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--rail-gap);
}

.filter-rail .rail-count {
  font-size: 0.8rem;
  color: var(--text-secondary);
  white-space: nowrap;
}

/* Toggles read as controls, not as stray text with a box in front. */
.filter-rail .admin-toggle,
.admin-toggle {
  height: var(--ctl-h);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--ctl-r);
  background: var(--bg-inset);
  font-size: 0.8rem;
  color: var(--text-secondary);
  white-space: nowrap;
  cursor: pointer;
}

.admin-toggle:hover { border-color: var(--border-strong); }
.admin-toggle input { accent-color: var(--accent-blue); cursor: pointer; }

/* --------------------------------------------------------------------------
   AUTH CARD

   The staff sign-in, the first-run setup and the members sign-in were three
   different widths, three heading sizes and three button treatments. One card.
   -------------------------------------------------------------------------- */
.admin-gate,
/* THE LAYOUT LIVES HERE BECAUSE THIS FILE LOADS LAST.
   members.css also defines .member-gate at the same specificity, so whatever
   this rule says wins. It used to centre a lone sign-in box in the viewport
   with flex, which put the box BESIDE the marketing section the moment one was
   added rather than below it. The page now stacks from the top: pitch, then
   form. Keep the layout in this one rule — two files describing the same box is
   how the last hour was spent. */
.member-gate {
  max-width: 62rem;
  margin: 0 auto;
  padding: 2.5rem 1.25rem 4rem;
  display: flex;
  flex-direction: column;
  /* stretch, not center: the hero row inside is a full-width two-column grid,
     and centring shrink-wrapped it to its content. */
  align-items: stretch;
  gap: 2.5rem;
}

.admin-gate-box,
.member-gate-box {
  width: 100%;
  max-width: 380px;
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg, 12px);
  padding: 1.75rem;
  text-align: left;
}

.admin-gate-box h2,
.member-gate-box h1,
.member-gate-box h2 {
  font-family: var(--font-heading);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 0.35rem;
}

.admin-gate-note,
.member-gate-note {
  font-size: 0.85rem;
  color: var(--text-secondary);
  line-height: 1.5;
  margin: 0 0 1.25rem;
}

.admin-gate-box form,
.member-gate-box form {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.admin-gate-box input,
.member-gate-box input {
  width: 100%;
}

.admin-gate-box button[type="submit"],
.member-gate-box button[type="submit"] {
  width: 100%;
  margin-top: 0.35rem;
}

/* An error is a direction, not a mood: it sits where the eye already is, under
   the control that failed, and takes no space until it has something to say. */
.admin-gate-error,
.member-gate-error {
  margin-top: 0.75rem;
  font-size: 0.82rem;
  color: var(--accent-red);
  min-height: 0;
}
.admin-gate-error:empty,
.member-gate-error:empty { margin-top: 0; }

/* A members field stacks its label above the control; the admin card places
   the label inside the placeholder. Both are legitimate, but they must share
   spacing and control height or the two sign-ins read as two products. */
.member-field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--text-secondary);
}

.member-field input { width: 100%; }

/* Mode switching is navigation, not three equal buttons: the current mode is
   already the heading, so the others are offered as plain links. */
.member-switch {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin-top: 1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border-subtle);
}

.member-switch .linkish {
  background: none;
  border: 0;
  padding: 0;
  font-family: var(--font-main);
  font-size: 0.82rem;
  color: var(--accent-blue);
  cursor: pointer;
}
.member-switch .linkish:hover { text-decoration: underline; }

.member-message {
  margin-top: 0.85rem;
  font-size: 0.82rem;
  color: var(--text-secondary);
  line-height: 1.5;
}
.member-message:empty { margin-top: 0; }

/* --------------------------------------------------------------------------
   DATA SURFACE

   The one place the design raises its voice. A lot list is read by scanning
   down a column, so the numerals are the content and everything else gets out
   of their way.
   -------------------------------------------------------------------------- */
.admin-table {
  font-size: 0.84rem;
}

.admin-table th {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: none; /* the caps were shouting a column name at every row */
  color: var(--text-secondary);
  background: var(--bg-inset);
  border-bottom: 1px solid var(--border-strong);
}

/* Numeric columns align right so magnitudes compare at a glance; the mono face
   keeps a six-figure yen value and a four-figure one the same width. */
.admin-table td.num,
.admin-table td[data-label="Price"],
.admin-table td[data-label="Mileage"],
.admin-table td[data-label="Year"] {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* A chassis code is a code. */
.admin-table .chassis,
.admin-table code {
  font-family: var(--font-mono);
  font-size: 0.92em;
  letter-spacing: 0.01em;
}

/* The inspection grade is the single most consulted field on a sheet, so it is
   the one thing allowed to look like a stamp. */
.grade-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  padding: 1px 6px;
  border: 1px solid currentColor;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.5;
}
.grade-chip.is-high { color: var(--accent-emerald); }
.grade-chip.is-mid  { color: var(--accent-gold); }
.grade-chip.is-low  { color: var(--accent-red); }

/* --------------------------------------------------------------------------
   RESPONSIVE

   The rail wraps rather than scrolls sideways: a filter you cannot see is a
   filter you will not use, and a horizontally scrolling control bar hides
   exactly the ones at the end.
   -------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------
   TOUCH AND SMALL SCREENS

   Three things matter here and none of them are layout.

   1. iOS Safari ZOOMS THE PAGE when a text input smaller than 16px takes
      focus, and does not zoom back out. A 14px filter box is the whole
      viewport jumping every time the operator taps search. The controls are
      34px on a mouse because density is the point; on a touch device they are
      16px type in a 44px target, which is the minimum a thumb can hit
      reliably.
   2. Nine controls wrapped to three rows push the data off the screen. The
      Filters button already exists and already toggles .filters-open, so the
      rail reuses it rather than inventing a second mechanism: search stays
      visible because it is the one control used every time, the rest fold
      away behind the button.
   3. The rail wraps, never scrolls sideways. A filter you cannot see is a
      filter you will not use, and a horizontally scrolling bar hides exactly
      the controls at the end.
   -------------------------------------------------------------------------- */
@media (pointer: coarse) {
  :root { --ctl-h: 44px; }

  .filter-input,
  .admin-input,
  input[type="search"],
  .admin-gate-box input,
  .member-field input,
  .member-field select,
  select.filter-input {
    /* 16px exactly. Anything below it triggers the zoom. */
    font-size: 16px;
  }

  .admin-toggle { min-height: 44px; }
  .admin-toggle input { width: 18px; height: 18px; }
}

@media (max-width: 720px) {
  .filter-rail {
    padding: 10px;
    gap: 8px;
  }

  .filter-rail .rail-search {
    flex: 1 1 100%;
    max-width: none;
  }

  .filter-rail .rail-divider { display: none; }

  /* The Filters button stays; it is what brings the rest back. */
  .filter-rail .rail-end {
    margin-left: auto;
    width: auto;
  }

  /* Folded away by default. The existing button toggles .filters-open on
     .admin-content, so this hangs off the same class rather than a new one. */
  .filter-rail .rail-field,
  .filter-rail .rail-end .admin-toggle {
    display: none;
  }

  .admin-content.filters-open .filter-rail .rail-field {
    display: flex;
    flex: 1 1 100%;
  }

  .admin-content.filters-open .filter-rail .rail-end {
    width: 100%;
    flex-wrap: wrap;
  }

  .admin-content.filters-open .filter-rail .rail-end .admin-toggle {
    display: inline-flex;
    flex: 1 1 100%;
  }

  /* A label and its control share the row, label first at a fixed width so
     the controls below it line up on one left edge instead of stepping. */
  .admin-content.filters-open .filter-rail .rail-field .rail-label {
    flex: 0 0 74px;
  }

  .admin-content.filters-open .filter-rail .rail-field select {
    flex: 1 1 auto;
    min-width: 0;
  }
}

/* The members sign-in and the staff card are already single column; they only
   need to stop being a fixed 380px on a 360px screen. */
@media (max-width: 420px) {
  .admin-gate,
  .member-gate { padding: 1.25rem 0.85rem; }

  .admin-gate-box,
  .member-gate-box { padding: 1.25rem; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* --------------------------------------------------------------------------
   MEMBERS

   Four areas now: cars for sale, auction lots, parts and market insight. The
   first three are things to shop; the fourth is reference, which is why it
   sits last rather than in the middle of them.
   -------------------------------------------------------------------------- */
.member-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 14px;
}

.member-card {
  display: flex;
  flex-direction: column;
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md, 10px);
  overflow: hidden;
}

/* A dealer card opens the car. It looked clickable long before it was, so the
   cursor and the focus ring now match what it actually does. */
.member-card[data-car] { cursor: pointer; }
.member-card[data-car]:hover { border-color: var(--border-strong, #999); }
.member-card[data-car]:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 2px;
}

.member-card-photo {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
  background: var(--bg-inset);
}
.member-card-photo.is-empty { border-bottom: 1px solid var(--border-subtle); }

.member-card-body { padding: 10px 12px 12px; }
.member-card-body h3 { font-size: 0.92rem; font-weight: 600; margin: 0 0 3px; }
.member-card-meta { font-size: 0.78rem; color: var(--text-secondary); margin: 0 0 6px; }
.member-card-price { font-size: 0.95rem; font-weight: 600; margin: 0; font-variant-numeric: tabular-nums; }
.member-card-price small { font-weight: 400; color: var(--text-secondary); }
/* Members see cars still inside the import window, which the public page hides.
   Stated plainly under the price rather than as a badge over the photo: it is
   a fact about the car, not a warning. */
.member-card-import {
  margin: 0.25rem 0 0;
  font-size: 0.78rem;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}

.member-muted { color: var(--text-muted); }
.chassis { font-family: var(--font-mono); font-size: 0.92em; }

/* Sub-navigation inside market insight. Quieter than the main tabs, because
   these switch a panel rather than an area. */
.member-subtabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0 0 1rem;
  padding-bottom: 2px;
  border-bottom: 1px solid var(--border-subtle);
}

.member-subtab {
  appearance: none;
  border: 0;
  background: transparent;
  padding: 7px 11px;
  border-radius: var(--ctl-r) var(--ctl-r) 0 0;
  font-family: var(--font-main);
  font-size: 0.85rem;
  color: var(--text-secondary);
  cursor: pointer;
}
.member-subtab:hover { color: var(--text-primary); background: var(--bg-inset); }
.member-subtab.active {
  color: var(--text-primary);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 var(--accent-red);
}

/* The one number worth reading first in the trend view. */
.market-headline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  margin-bottom: 1rem;
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md, 10px);
}
.market-headline-num {
  font-size: 1.5rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.spark { display: block; margin-left: auto; }
.is-up { color: var(--accent-emerald); }
.is-down { color: var(--accent-red); }

.member-callout {
  padding: 14px 16px;
  margin-bottom: 1.25rem;
  background: var(--bg-inset);
  border: 1px solid var(--border-subtle);
  border-left: 3px solid var(--accent-red);
  border-radius: var(--radius-md, 10px);
}
.member-callout h3 { font-size: 0.95rem; font-weight: 600; margin: 0 0 4px; }
.member-callout p { margin: 0; font-size: 0.88rem; line-height: 1.55; color: var(--text-secondary); }

.insight-table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   MORE FILTERS

   Eight further controls, revealed by the button in the rail. A grid rather
   than another row of inline fields: ranges and selects have different natural
   widths, and lining them into columns is what stops eight controls reading as
   clutter. Labels sit above here, unlike the rail, because a two-line field in
   a grid costs nothing and a range needs its unit stated.
   -------------------------------------------------------------------------- */
.member-morefilters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px 12px;
  align-items: end;
  padding: 14px;
  margin: -6px 0 14px;
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md, 10px);
}

.mf-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  font-size: 0.76rem;
  font-weight: 500;
  color: var(--text-secondary);
}

.mf-field .filter-input { width: 100%; }

/* The clear action sits at the end of the grid and takes a whole cell, so it
   is never mistaken for another filter. */
.mf-actions {
  grid-column: 1 / -1;
  display: flex;
  justify-content: flex-end;
  padding-top: 2px;
}

/* Number inputs lose their spinners: a year is typed, not nudged, and the
   arrows steal width from a field that already shows four digits. */
.member-morefilters input[type="number"] { -moz-appearance: textfield; }
.member-morefilters input[type="number"]::-webkit-outer-spin-button,
.member-morefilters input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* --------------------------------------------------------------------------
   VERTICAL BUDGET ABOVE THE CONTENT

   The dealer view stacked a page header, a tab row, a heading with a summary
   line and then the filter rail — four bands before the first car, which on a
   laptop pushed the cars below the fold. The heading is gone (the tab names
   the view) and what remains is tightened.
   -------------------------------------------------------------------------- */

/* A status line that says nothing takes no space. */
.member-status:empty { display: none; }
.member-status {
  margin: -4px 0 10px;
  font-size: 0.84rem;
  color: var(--text-secondary);
}

/* The rail is the first thing in a view now, so it does not need to clear a
   heading above it. */
.member-view > .filter-rail:first-child { margin-top: 0; }

.member-view-head {
  margin-bottom: 0.9rem;
}
.member-view-head h2 {
  font-size: 1.15rem;
  line-height: 1.25;
}

/* Tabs sit closer to the content they switch. */
.member-tabs { margin-bottom: 1rem; }

/* --------------------------------------------------------------------------
   SHEET DECODE REEL
   -------------------------------------------------------------------------- */
.reel-hook {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
  margin: 12px 0 4px;
  padding: 12px 14px;
  background: var(--bg-inset);
  border-left: 3px solid var(--accent-red);
  border-radius: var(--radius-md, 10px);
}
.reel-hook-label { font-size: 0.72rem; color: var(--text-muted); }
.reel-hook-line { font-size: 1.15rem; font-weight: 600; line-height: 1.3; }
.reel-warn { font-size: 0.75rem; color: var(--accent-red); }

.reel-beats { table-layout: auto; margin-top: 10px; }
.reel-beats td { white-space: normal; vertical-align: top; }
.reel-beats td.num { width: 3.5rem; font-family: var(--font-mono); color: var(--text-muted); }

.reel-copy {
  margin: 4px 0 12px;
  padding: 10px 12px;
  background: var(--bg-inset);
  border: 1px solid var(--border-subtle);
  border-radius: var(--ctl-r);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  white-space: pre-wrap;
  word-break: break-word;
}
.admin-muted { color: var(--text-muted); }
.reel-sound { margin: 6px 0 10px; }
.reel-sound p { margin: 0 0 6px; font-size: 0.86rem; }
.reel-rules { margin: 6px 0 0; padding-left: 1.1rem; font-size: 0.82rem; color: var(--text-secondary); }
.reel-rules li { margin-bottom: 4px; }

/* --------------------------------------------------------------------------
   AUCTION SHEET, READ BY A MEMBER
   -------------------------------------------------------------------------- */
.lot-sheet { margin-top: 1rem; }
.sheet-summary {
  margin: 10px 0;
  padding: 12px 14px;
  background: var(--bg-inset);
  border-left: 3px solid var(--accent-red);
  border-radius: var(--radius-md, 10px);
  font-size: 0.9rem;
  line-height: 1.55;
}
.lot-sheet h4 {
  margin: 14px 0 6px;
  font-size: 0.85rem;
  font-weight: 600;
}
.sheet-list { margin: 0; padding-left: 1.1rem; font-size: 0.86rem; line-height: 1.6; }
.sheet-list li { margin-bottom: 3px; }

/* Label and value in two columns, so a sheet reads like the document it is
   rather than as a paragraph of colon-separated pairs. */
.sheet-fields {
  display: grid;
  grid-template-columns: minmax(7rem, auto) 1fr;
  gap: 2px 14px;
  margin: 0;
  font-size: 0.84rem;
}
.sheet-fields dt { color: var(--text-secondary); }
.sheet-fields dd { margin: 0; font-variant-numeric: tabular-nums; }

.member-news { font-size: 0.8rem; }
