/* ===========================================================================
   artcaremiles.club — the one and only stylesheet.
   Bands: Reset · Tokens · Typography · Layout · Components · Utilities · Motion
   No <style> blocks and no style="" attributes anywhere: the CSP forbids both.
   =========================================================================== */

/* --- Reset ---------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

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

body, h1, h2, h3, h4, p, ul, ol, figure, dl, dd { margin: 0; }
ul[class], ol[class] { list-style: none; padding: 0; }

img, svg { display: block; max-width: 100%; }

/* An AUTHOR display rule always beats the UA stylesheet's [hidden]{display:none},
   however low its specificity -- so any component with its own display value
   would ignore the hidden attribute entirely without this. */
[hidden] { display: none !important; }

/* 16px exactly on anything focusable, or iOS Safari zooms the page on focus. */
input, select, textarea, button { font: inherit; font-size: 16px; color: inherit; }

button { background: none; border: 0; padding: 0; cursor: pointer; }

/* --- Tokens --------------------------------------------------------------- */

:root {
  /* Raw palette. Conservation lab: raw linen, iron-gall ink, verdigris,
     ochre, madder. Contrast ratios are against --paper. */
  --paper:        #FAF6EF;  /* page */
  --paper-raised: #FFFCF7;  /* cards */
  --linen:        #EFE7DA;  /* hairlines, ring track */
  --linen-deep:   #E2D7C5;  /* input borders, disabled */

  --ink:          #1F1B16;  /* primary text        — 14.2:1 */
  --ink-soft:     #5C5349;  /* secondary text      —  6.9:1 */
  --ink-faint:    #6E6456;  /* meta, captions      —  5.4:1 on paper, 4.7:1 on linen */

  /* The verdigris split matters and is the thing most likely to be gotten
     wrong later. --verdigris is for the progress arc and other NON-TEXT
     marks (needs only 3:1 against --linen). --verdigris-dp is the ONLY green
     permitted for text or meaning-bearing icons. */
  --verdigris:    #4C7A6B;  /* non-text marks      —  3.9:1 */
  --verdigris-dp: #35584D;  /* text, icons, focus  —  6.3:1 */

  --ochre:        #8E5B22;  /* reward links       —  5.3:1 on paper, 4.7:1 on linen */
  --gold-leaf:    #C9A227;  /* goal met, once per card at most */
  --madder:       #9A3B33;  /* destructive only    —  6.0:1 */
  --plum:         #6B4B63;  /* admin chrome only — a different room */

  /* Semantic aliases — components reference these, never the raw names. */
  --bg: var(--paper);
  --surface: var(--paper-raised);
  --rule: var(--linen);
  --text: var(--ink);
  --muted: var(--ink-soft);
  --faint: var(--ink-faint);
  --accent: var(--verdigris);
  --accent-text: var(--verdigris-dp);
  --success: var(--gold-leaf);
  --danger: var(--madder);

  /* Space scale */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px;

  --radius: 10px;
  /* Enough for mm/dd/yyyy plus the native picker glyph. */
  --date-w: 10.5rem;
  --hairline: 1px solid var(--rule);
  --lift: 0 1px 2px rgb(31 27 22 / 0.04);

  --measure: 68rem;
}

/* --- Typography ----------------------------------------------------------- */

/* Self-hosted variable faces. Files land in assets/fonts/ during Phase 3;
   until then the fallback stacks below carry the design. Self-hosting keeps
   font-src 'self' in the CSP, costs no third-party connection on a cold
   mobile network, and leaves no privacy question. */
@font-face {
  font-family: 'Fraunces';
  src: url('../fonts/fraunces-var.woff2') format('woff2-variations');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'InterVar';
  src: url('../fonts/inter-var.woff2') format('woff2-variations');
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --font-display: 'Fraunces', 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --font-ui: 'InterVar', -apple-system, BlinkMacSystemFont, 'Segoe UI',
             Roboto, Helvetica, Arial, sans-serif;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 1rem;
  line-height: 1.6;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, .display {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 72;
  font-optical-sizing: auto;
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

h1 { font-size: clamp(2rem, 8vw, 3rem); }
h2 { font-size: 1.625rem; }
h3 { font-size: 1.25rem; }

/* Section eyebrow: small caps, tracked out. */
.eyebrow {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Every mileage figure, everywhere. Keeps rings and columns from jittering
   as digits change. */
.figure {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

.lede  { font-size: 1.25rem; color: var(--muted); text-wrap: pretty; }
/* Empty unless the organiser has set a note under the title. */
.lede:empty { display: none; }
.meta  { font-size: 0.8125rem; color: var(--faint); }
.small { font-size: 0.9375rem; }

a { color: var(--accent-text); text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
  outline: 2px solid var(--verdigris-dp);
  outline-offset: 2px;
  border-radius: 2px;
}

/* --- Layout --------------------------------------------------------------- */

.skiplink {
  position: absolute;
  left: -9999px;
  top: var(--s-2);
  padding: var(--s-2) var(--s-4);
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  color: var(--accent-text);
  z-index: 10;
}
.skiplink:focus { left: var(--s-4); }

.wrap {
  width: 100%;
  max-width: var(--measure);
  margin-inline: auto;
  padding-inline: clamp(1rem, 5vw, 2.5rem);
}

.masthead {
  padding-top: calc(var(--s-7) + env(safe-area-inset-top, 0px));
  padding-bottom: var(--s-6);
  text-align: center;
}

/* The motion sequence. One wide element rather than a mark repeated on every
   card: at this width the frames read as a frieze, and the file fades to
   transparent at both ends so it has no hard edge against the paper. */
.masthead__sequence {
  width: 100%;
  max-width: 44rem;
  height: auto;
  margin: var(--s-5) auto var(--s-4);
  /* multiply keeps the lighter tones sitting in the paper rather than on it. */
  mix-blend-mode: multiply;
  opacity: .92;
}

.credit { margin-top: var(--s-2); font-size: .75rem; }
.credit em { font-style: italic; }

.masthead .small a,
.panel__help a {
  display: inline-block;
  min-height: 24px;
  padding: var(--s-1) var(--s-1);
}

.masthead__rule {
  width: 72px;
  height: 1px;
  margin: var(--s-5) auto;
  background: var(--linen-deep);
  border: 0;
}

/* --- Components ----------------------------------------------------------- */

/* Month switcher ----------------------------------------------------------- */

.monthnav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  padding-bottom: var(--s-5);
}

.monthnav__label {
  min-width: 10.5rem;
  margin: 0;
  text-align: center;
  font-size: 1.375rem;
}

.monthnav__step {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: var(--hairline);
  border-radius: 50%;
  background: var(--surface);
  color: var(--accent-text);
  font-size: 1.25rem;
  line-height: 1;
  transition: background-color .15s ease, border-color .15s ease;
}
.monthnav__step:hover:not(:disabled) { background: var(--linen); }
.monthnav__step:disabled { color: var(--ink-faint); opacity: .5; cursor: default; }

/* The group band ----------------------------------------------------------- */

.band {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-6) var(--s-5);
  margin-bottom: var(--s-5);
  background: var(--surface);
  border: var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  text-align: center;
}

/* Emptying a container leaves the container: without this, a board that
   cannot load shows an empty bordered box where the group ring would be. */
.band:empty, .monthnav:empty, .grid:empty { display: none; }

.band__line { font-family: var(--font-display); font-size: 1.25rem; line-height: 1.3; }
.band__sub { margin-top: var(--s-1); }

@media (min-width: 40rem) {
  .band {
    flex-direction: row;
    /* Centred as a pair. Left-aligned, the ring and its text hugged the edge
       of a very wide panel with a screenful of empty space beside them. */
    justify-content: center;
    gap: var(--s-6);
    text-align: left;
    padding: var(--s-6);
  }
  .band__line { font-size: 1.625rem; }
}

/* Notices ------------------------------------------------------------------ */

.notice {
  margin-bottom: var(--s-5);
  padding: var(--s-3) var(--s-4);
  border-left: 2px solid var(--linen-deep);
  color: var(--muted);
  font-size: 0.9375rem;
}

.status:empty { display: none; }
.status { text-align: center; padding-bottom: var(--s-4); }

/* A button that reads as a link. Used where the action is navigation. */
.linkish {
  color: var(--accent-text);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* The board ---------------------------------------------------------------- */

.grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-4);
}

@media (min-width: 33rem) { .grid { grid-template-columns: repeat(2, 1fr); gap: var(--s-5); } }
@media (min-width: 55rem) { .grid { grid-template-columns: repeat(3, 1fr); } }

.card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-5) var(--s-4);
  background: var(--surface);
  border: var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  text-align: center;
}

/* Identity, NOT rank. Every card is the same size and weight; nothing marks
   a position. The board is sorted, but it is not a podium. */
.card--you { border-color: var(--accent); }

.card__name {
  margin: 0;
  font-size: 1.125rem;
  /* A long name wraps rather than truncating -- it is someone's name. */
  overflow-wrap: break-word;
  hyphens: auto;
}

.card__status { font-size: 0.9375rem; color: var(--muted); }
/* Same typeface and size as the line it replaces: only weight and colour
   change, so the card does not switch fonts depending on someone's progress. */
.card__status--met {
  font-weight: 600;
  color: var(--accent-text);
}

.card__meta { margin: 0; }

.card__reward { margin: 0; padding-top: var(--s-1); }
/* An inline link in flowing text was only 18px tall. WCAG 2.5.8 asks for a
   24x24 minimum target, which padding supplies without changing the type. */
.card__rewardlink {
  display: inline-block;
  min-height: 24px;
  padding: var(--s-1) var(--s-2);
  color: var(--ochre);
  font-size: 0.9375rem;
}

/* A URL that failed validation renders as inert text, never a live link. */
.link--inert { color: var(--faint); font-size: 0.9375rem; }

/* Pills -------------------------------------------------------------------- */

.pill {
  display: inline-block;
  margin-left: var(--s-2);
  padding: 2px var(--s-2);
  border-radius: 999px;
  font-family: var(--font-ui);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: 2px;
}

.pill--you  { background: var(--linen); color: var(--accent-text); }

/* The progress ring -------------------------------------------------------- */

.ringwrap { position: relative; display: grid; place-items: center; flex-shrink: 0; }
.ringwrap--card { width: 112px; height: 112px; }
.ringwrap--band { width: 160px; height: 160px; }

.ring {
  width: 100%;
  height: 100%;
  /* The rotation lives on the svg so the dash arithmetic stays trivial. */
  transform: rotate(-90deg);
}

.ring__track, .ring__arc {
  fill: none;
  stroke-width: 7;
  stroke-linecap: round;
}

.ring__track { stroke: var(--linen); }

/* At zero the track goes dashed, so an untouched card -- and the whole board
   on the 1st -- reads as deliberate rather than broken. */
.ring__track--empty { stroke-dasharray: 2 6; stroke: var(--linen-deep); }

.ring__arc {
  stroke: var(--verdigris);
  transition: stroke-dashoffset .9s cubic-bezier(.22, 1, .36, 1), stroke .4s ease;
}

.ring--complete .ring__arc { stroke: var(--gold-leaf); }

.ringwrap__text {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  text-align: center;
  line-height: 1.1;
}

.ringwrap__figure {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.02em;
}
.ringwrap--card .ringwrap__figure { font-size: 1.625rem; }
.ringwrap--band .ringwrap__figure { font-size: 2.25rem; }

.ringwrap__caption { font-size: 0.75rem; color: var(--faint); }

/* An empty card should not shout a zero. */
.ring--card:not(.ring--complete) + .ringwrap__text .ringwrap__figure { color: var(--text); }

/* The logging panel ------------------------------------------------------- */

.logger {
  padding: var(--s-5) var(--s-4) calc(var(--s-5) + env(safe-area-inset-bottom, 0px));
  margin-bottom: var(--s-5);
  background: var(--linen);
  border: 1px solid var(--linen-deep);
  border-radius: var(--radius);
}

.logger.is-busy { opacity: .6; pointer-events: none; }

/* The panel's ground spans the column like the group band above it, but its
   CONTROLS are capped and centred. Left to stretch, a wide screen gave this a
   236px-wide "+1" chip and an 830px field holding one number. */
.logger > * { max-width: 34rem; margin-inline: auto; }
.logger .eyebrow { display: block; margin-bottom: var(--s-3); }

/* Quick-add chips. These ADD to the pending amount rather than logging, so a
   distance like 3.2 is reachable with taps alone and never needs a keyboard. */
.chips { display: flex; flex-wrap: wrap; gap: var(--s-2); }

.chip {
  flex: 1 1 auto;
  min-width: 4rem;
  min-height: 48px;
  padding: 0 var(--s-3);
  border: 1px solid var(--linen-deep);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text);
  /* Inter, like every other control in this panel. These are buttons that
     happen to contain a number, not display figures. */
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  transition: background-color .12s ease, border-color .12s ease, transform .08s ease;
}
.chip:hover { border-color: var(--accent); }
.chip:active { transform: scale(.97); }

/* The pending amount, with the steppers broken out either side. The native
   number spinner is suppressed below: on a phone its two arrows are stacked
   into roughly one thumb-width, which is how you tick up when you meant down. */
.amount {
  display: flex;
  align-items: stretch;
  gap: var(--s-2);
  margin-top: var(--s-3);
}

.step {
  flex: 0 0 auto;
  width: 64px;
  min-height: 64px;
  border: 1px solid var(--linen-deep);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--accent-text);
  font-size: 1.5rem;
  line-height: 1;
  transition: background-color .12s ease, border-color .12s ease, transform .08s ease;
}
.step:hover:not(:disabled) { border-color: var(--accent); }
.step:active:not(:disabled) { transform: scale(.96); }
.step:disabled { color: var(--ink-faint); opacity: .55; cursor: default; }

.amount__field {
  position: relative;
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--s-1);
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--linen-deep);
  border-radius: var(--radius);
  background: var(--surface);
}

.amount__value {
  width: 100%;
  min-width: 0;
  border: 0;
  background: transparent;
  text-align: right;
  font-family: var(--font-display);
  /* Comfortably above the 16px floor that stops iOS zooming on focus. */
  font-size: 2rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}
.amount__value:focus { outline: none; }

/* The placeholder must not read as a real value, or an empty field looks like
   it holds zero. */
.amount__value::placeholder { color: var(--faint); opacity: 1; }
.amount__field:focus-within { border-color: var(--accent); }

/* Suppress the native spinner -- the .step buttons replace it. */
.amount__value::-webkit-outer-spin-button,
.amount__value::-webkit-inner-spin-button { appearance: none; margin: 0; }
.amount__value { appearance: textfield; -moz-appearance: textfield; }

.amount__unit { flex: 0 0 auto; color: var(--faint); font-size: 1rem; }

/* Base controls, shared by the logger and (later) the admin console. */

.field {
  min-height: 48px;
  padding: 0 var(--s-3);
  border: 1px solid var(--linen-deep);
  border-radius: var(--radius);
  background: var(--surface);
  /* font-size is inherited from the global 16px rule: anything smaller makes
     iOS Safari zoom the whole page on focus. */
}
/* Today and the picker read as one pair, with exactly one of the two looking
   selected, so the row never shows a lone field floating in space. */
.daybtn {
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 var(--s-4);
  border: 1px solid var(--linen-deep);
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.daybtn:hover { border-color: var(--accent); }
.daybtn.is-on,
.field--date.is-on {
  background: var(--surface);
  border-color: var(--accent);
  color: var(--accent-text);
  font-weight: 600;
}

/* A native date input, dressed to match. Its text format belongs to the
   browser and cannot be changed; everything around it can. */
.field--date {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: 0 var(--s-3);
  border: 1px solid var(--linen-deep);
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.field--date:hover { border-color: var(--accent); }

/* The picker glyph, toned into the palette rather than left as a stock icon. */
.field--date::-webkit-calendar-picker-indicator {
  opacity: .4;
  margin-left: var(--s-2);
  cursor: pointer;
  transition: opacity .12s ease;
}
.field--date:hover::-webkit-calendar-picker-indicator,
.field--date.is-on::-webkit-calendar-picker-indicator { opacity: .75; }
.field--date::-webkit-date-and-time-value { text-align: left; }

.btn {
  min-height: 48px;
  padding: 0 var(--s-4);
  border-radius: var(--radius);
  background: var(--accent-text);
  color: var(--paper);
  font-weight: 600;
}
.btn:hover:not(:disabled) { background: var(--ink); }

.logger__actions {
  display: flex;
  justify-content: center;
  margin-top: var(--s-3);
}

/* Centred and capped rather than full width: it then sits on the same axis as
   the Today/date pair above it, and a max-width stops it stretching to the
   whole panel on a wide screen, where the panel itself is very wide. */
.btn--log { width: 100%; max-width: var(--logger-w); }
.btn:disabled { background: var(--linen-deep); color: var(--ink-faint); cursor: default; }

/* Today + the picker, and Log below them, share ONE width and are centred, so
   their left and right edges line up. Narrower than the chips and amount above
   (those are what you use most), but not so narrow the date clips. */
.logger { --logger-w: 18rem; }
.logger__when {
  display: grid;
  grid-template-columns: auto minmax(var(--date-w), 1fr);
  align-items: center;
  gap: var(--s-2);
  width: 100%;
  max-width: var(--logger-w);
  margin: var(--s-3) auto 0;
}

.amount__clear {
  position: absolute;
  left: var(--s-1);
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--ink-faint);
  font-size: 1.25rem;
  line-height: 1;
}
.amount__clear:hover { background: var(--linen); color: var(--ink); }
/* Keeps its footprint when inapplicable, so nothing beside it shifts. */
.amount__clear.is-hidden { visibility: hidden; }

.logger__message { margin-top: var(--s-3); font-size: .9375rem; min-height: 1.4em; }
.logger__message--error { color: var(--danger); }
.logger__message--success { color: var(--accent-text); }
.logger__empty { margin-top: var(--s-4); }

/* Your own entries, with a way to take one back. Collapsed, so the panel is a
   fixed height whether you have logged twice or forty times. */
.entries__wrap { margin-top: var(--s-4); border-top: var(--hairline); }

.entries__summary {
  list-style: none;
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-2);
  min-height: 44px;
  padding: var(--s-3) var(--s-6) var(--s-3) 0;
  cursor: pointer;
  font-size: 0.9375rem;
  font-weight: 600;
}
.entries__summary::-webkit-details-marker { display: none; }

.entries__summary::after {
  content: '';
  position: absolute;
  right: var(--s-2);
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -6px;
  border-right: 2px solid var(--accent-text);
  border-bottom: 2px solid var(--accent-text);
  transform: rotate(45deg);
  transition: transform .15s ease;
}
.entries__wrap[open] .entries__summary::after { transform: rotate(-135deg) translateY(-3px); }

.entries__summary:hover { color: var(--accent-text); }
.entries__count { font-weight: 400; }

.entries { border-top: var(--hairline); }

.entries__row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) 0;
  border-bottom: var(--hairline);
}

.entries__date { flex: 0 0 3.5rem; }
.entries__miles { flex: 1 1 auto; font-family: var(--font-display); }

.entries__remove {
  min-height: 36px;
  padding: 0 var(--s-2);
  color: var(--muted);
  font-size: .8125rem;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.entries__remove:hover { color: var(--danger); }
.entries__remove:disabled { opacity: .5; }

/* Footer ------------------------------------------------------------------- */

.footer {
  margin-top: var(--s-8);
  padding: var(--s-5) 0 calc(var(--s-7) + env(safe-area-inset-bottom, 0px));
  border-top: var(--hairline);
  text-align: center;
}

/* --- Motion --------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Admin console -------------------------------------------------------- */
/* A different room from the board: plum chrome, denser, more utilitarian. */

.admin .masthead--admin .eyebrow { color: var(--plum); }

.panel {
  padding: var(--s-5) var(--s-4);
  margin-bottom: var(--s-5);
  background: var(--surface);
  border: var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--lift);
}
.panel h2 { font-size: 1.375rem; }

/* Cap the form controls, not the panels. On a wide screen the roster rows
   want the full width -- name left, miles and actions right -- but a text
   field stretched to 974px for a club name, or a dropdown to 817px for a
   one-word choice, just looks broken. The fixed-width controls inside a
   correction row are narrower than this already, so they are unaffected. */
.panel input:not([type="checkbox"]):not([type="radio"]),
.panel select,
.panel textarea { max-width: 26rem; }

/* One line of plain help per section. The organizer will never open a manual,
   so the interface has to teach itself. */
.panel__help {
  margin: var(--s-2) 0 var(--s-4);
  color: var(--muted);
  font-size: .9375rem;
  font-style: italic;
}

.addform { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s-2); }
.addform__label { flex: 1 1 100%; font-size: .8125rem; color: var(--muted); }
.addform .field { flex: 1 1 12rem; }

/* The one-time link panel. Deliberately loud: this is the only moment the
   link exists, and missing it means re-issuing. */
.outbox {
  margin: var(--s-4) 0;
  padding: var(--s-4);
  border: 1px solid var(--gold-leaf);
  border-radius: var(--radius);
  background: var(--paper);
}
.outbox__title { font-family: var(--font-display); font-size: 1.125rem; }
.outbox__note { margin: var(--s-2) 0 var(--s-3); font-size: .875rem; color: var(--muted); }
.outbox__list { display: grid; gap: var(--s-3); }
.outbox__row { display: grid; gap: var(--s-2); padding-bottom: var(--s-3); border-bottom: var(--hairline); }
.outbox__name { font-weight: 600; }
.outbox__url {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .8125rem;
  color: var(--muted);
  overflow-wrap: anywhere;
}
.outbox__actions, .outbox__footer { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; }
.outbox__footer { margin-top: var(--s-3); }

.roster__count { margin: var(--s-4) 0 var(--s-2); }

.person { padding: var(--s-3) 0; border-bottom: var(--hairline); }
/* Fade the name line only. Fading the whole row also faded Put back in the
   club, the one thing on it she is there to press. */
.person--removed .person__head { opacity: .65; }
/* A grid, not a wrapping flex row: with flex, whether Edit fitted on the first
   line depended on how long the name and the pill happened to be, so rows
   broke in different places. Now every row breaks the same way. */
.person__head {
  display: grid;
  grid-template-columns: 1fr auto auto;
  grid-template-areas:
    "name miles toggle"
    "link miles toggle";
  align-items: center;
  column-gap: var(--s-3);
  row-gap: var(--s-1);
}
.person__head .person__name { grid-area: name; font-weight: 600; }
.person__miles { grid-area: miles; font-family: var(--font-display); }
.person__link { grid-area: link; justify-self: start; }
.person__head .person__toggle { grid-area: toggle; }

@media (min-width: 34rem) {
  .person__head {
    grid-template-columns: 1fr auto auto auto;
    grid-template-areas: "name link miles toggle";
  }
}

.person__toggle {
  min-height: 40px;
  padding: 0 var(--s-3);
  border: var(--hairline);
  border-radius: 999px;
  color: var(--muted);
  font-size: .875rem;
}
.person__toggle:hover { border-color: var(--accent); color: var(--accent-text); }
/* A chevron drawn from two borders, so it takes the text colour and needs no
   icon file. Points down when closed, up when open. */
.person__toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.person__toggle::after {
  content: "";
  width: 6px;
  height: 6px;
  margin-top: -3px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform .15s ease;
}
.person__toggle[aria-expanded="true"]::after { margin-top: 3px; transform: rotate(-135deg); }
@media (prefers-reduced-motion: reduce) { .person__toggle::after { transition: none; } }

.person__details { display: grid; gap: var(--s-3); padding: var(--s-3) 0 var(--s-2); }
.person__label { display: grid; gap: var(--s-1); font-size: .8125rem; color: var(--muted); }
.person__label .field { width: 100%; }
.person__buttons { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
/* Save, the link button and Remove on one line even on a 360px phone. */
@media (max-width: 23.4rem) {
  .person__buttons .btn { padding-inline: var(--s-2); }
}

.btn--small { min-height: 40px; padding: 0 var(--s-3); font-size: .9375rem; }
.btn--quiet { background: transparent; color: var(--accent-text); border: 1px solid var(--linen-deep); }
.btn--quiet:hover:not(:disabled) { background: var(--linen); color: var(--accent-text); }

.linkish--danger { color: var(--danger); }

/* Outlined in the danger colour: Remove, never anything else. */
.btn--danger { background: transparent; color: var(--danger); border: 1px solid currentColor; }
.btn--danger:hover:not(:disabled) { background: var(--danger); color: var(--paper-raised); }

.pill--ok      { background: var(--linen); color: var(--accent-text); text-transform: none; letter-spacing: 0; }
.pill--waiting { background: #F6ECD6; color: #7A5A12; text-transform: none; letter-spacing: 0; }
.pill--off     { background: var(--linen); color: var(--muted); text-transform: none; letter-spacing: 0; }
.pill--admin   { background: #EFE6EE; color: #5A3E53; text-transform: none; letter-spacing: 0; }

/* Checkboxes. accent-color tints the native control to the palette, which is
   far more robust than rebuilding one out of pseudo-elements. */
.check {
  display: grid;
  grid-template-columns: 24px 1fr;
  align-items: start;
  gap: var(--s-3);
  padding: var(--s-2) 0;
  font-size: .9375rem;
  line-height: 1.45;
  cursor: pointer;
}
.check + .check { border-top: var(--hairline); }
.check input {
  /* 24px is the WCAG 2.5.8 minimum. The whole label is clickable, so the real
     target is larger, but a bigger box is easier to hit directly. */
  width: 24px;
  height: 24px;
  margin: 0;
  /* Nudged to sit on the first line's optical centre rather than its top. */
  margin-top: .15em;
  cursor: pointer;
}
.check:hover { color: var(--text); }

/* The consequence of each choice, stated under it. */
.check__hint {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: .8125rem;
  line-height: 1.4;
}

.person__label--head { margin-bottom: calc(var(--s-2) * -1); font-weight: 600; color: var(--text); }

/* The settings fields get an even rhythm from one place rather than each
   control carrying its own margin. */
#settings { display: grid; gap: var(--s-4); }
#settings .person__buttons { margin-top: calc(var(--s-1) * -1); }

.checkgroup {
  padding: var(--s-1) var(--s-3);
  background: var(--paper);
  border-radius: var(--radius);
}

.goals { margin-top: var(--s-5); padding-top: var(--s-4); border-top: var(--hairline); }
.goals summary { cursor: pointer; color: var(--muted); font-size: .9375rem; padding: var(--s-2) 0; }
.goals__list { margin-top: var(--s-1); font-size: .9375rem; color: var(--muted); }
.goals__list li { padding: var(--s-1) 0; }

.roster__removed { margin-top: var(--s-5); }
.roster__removed summary { cursor: pointer; color: var(--muted); font-size: .9375rem; padding: var(--s-2) 0; }

/* Corrections --------------------------------------------------------------- */

.fixbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  padding-bottom: var(--s-4);
  border-bottom: var(--hairline);
}
.fixbar .person__label { flex: 1 1 12rem; margin: 0; }
.fixbar .check { flex: 0 1 auto; border: 0; }

.fixadd {
  margin: var(--s-4) 0 var(--s-5);
  padding: var(--s-4);
  background: var(--paper);
  border-radius: var(--radius);
}
/* Two rows on a phone — who and how far, then when and Add — with Add
   stretched to end under Miles so the block has one right edge. */
.fixadd__row {
  display: grid;
  grid-template-columns: var(--date-w) 1fr;
  gap: var(--s-2);
  margin-top: var(--s-3);
}
.fixadd__row .field { min-height: 44px; min-width: 0; }
.fixadd__go { min-height: 44px; }

@media (min-width: 34rem) {
  .fixadd__row { grid-template-columns: 1fr 6rem var(--date-w) auto; }
}

/* A row per entry, each on its own tinted card so one person's controls are
   never read as the next person's. On a phone: name with Remove beside it,
   then miles, date and Save on one line. Wider: everything on one line. */
.fixlist { display: grid; gap: var(--s-2); }
.fixrow {
  display: grid;
  /* Miles gets its minimum first (room for 49.75); the date gives up its
     spare width on a narrow phone rather than the miles clipping. */
  grid-template-columns: 4rem minmax(0, var(--date-w)) auto;
  grid-template-areas:
    "head  head head"
    "miles date save";
  align-items: center;
  gap: var(--s-2) 6px;
  padding: var(--s-3) var(--s-2);
  background: var(--paper);
  border-radius: var(--radius);
}
/* Tighter insides on a phone: 49.75 and mm/dd/yyyy must both show whole on a
   360px Android screen, with Save still on the same line. */
.fixrow > .field--mini,
.fixrow__save,
.fixrow__corner { padding-inline: var(--s-2); }
/* Save and Remove stack in the same corner on a phone; one width keeps them
   reading as a pair. Not below 375px, where those 8px are the date's. */
@media (min-width: 23.4rem) {
  .fixrow__save,
  .fixrow__corner { min-width: 4.75rem; }
}
.fixrow--deleted { opacity: .55; }
/* Name and Remove share their own line on a phone, so Remove's width never
   steals from the date column below. */
.fixrow__head {
  grid-area: head;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
}
.fixrow__name { grid-area: name; font-weight: 600; font-size: .9375rem; }
.fixrow__corner { grid-area: corner; flex: 0 0 auto; }
.fixrow > input[type="number"] { grid-area: miles; }
/* .field--mini in the selector to outrank the min-width guard on date fields
   below; the column itself is what keeps the date from clipping here. */
.fixrow > input[type="date"].field--mini { grid-area: date; min-width: 0; width: 100%; }
.fixrow__save { grid-area: save; }

@media (min-width: 34rem) {
  .fixrow {
    grid-template-columns: minmax(6rem, 1fr) 6rem var(--date-w) auto auto;
    grid-template-areas: "name miles date save corner";
    gap: var(--s-3);
  }
  /* Wider, the head's two children join the row's own grid. */
  .fixrow__head { display: contents; }
}

/* Date inputs need room for mm/dd/yyyy AND the picker glyph. Too narrow and
   the browser silently clips the value, which is how 10/06/2026 rendered as
   "10/06/2(". --date-w is declared with the other tokens. */
.field--mini { min-height: 44px; min-width: 0; }
input[type="date"].field,
input[type="date"].field--mini { min-width: var(--date-w); }


/* Form controls, drawn rather than left native -------------------------------
   A native select and checkbox render with the browser's own chevron and box,
   which sit oddly beside pills and fields that were designed. These replace
   both while keeping real <select> and <input> elements, so keyboard
   behaviour, focus and the mobile pickers are untouched. */

select.field {
  appearance: none;
  -webkit-appearance: none;
  padding-right: var(--s-6);
  background-image: url("data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20width='12'%20height='8'%20viewBox='0%200%2012%208'><path%20d='M1%201l5%205%205-5'%20fill='none'%20stroke='%235C5349'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right var(--s-3) center;
  background-size: 12px 8px;
  cursor: pointer;
}
select.field:hover { border-color: var(--accent); }

.check input[type="checkbox"],
.check input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  width: 24px;
  height: 24px;
  margin: 0;
  margin-top: .1em;
  display: grid;
  place-content: center;
  border: 1px solid var(--linen-deep);
  background: var(--surface);
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}
.check input[type="checkbox"] { border-radius: 6px; }
.check input[type="radio"]    { border-radius: 50%; }

.check:hover input { border-color: var(--accent); }

.check input:checked {
  background: var(--verdigris-dp);
  border-color: var(--verdigris-dp);
}

/* The tick: two borders of a rotated box, so there is no second asset. */
.check input[type="checkbox"]:checked::after {
  content: '';
  width: 6px;
  height: 11px;
  margin-top: -2px;
  border: solid var(--paper);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.check input[type="radio"]:checked {
  background: var(--surface);
  border-color: var(--verdigris-dp);
}
.check input[type="radio"]:checked::after {
  content: '';
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--verdigris-dp);
}

/* Help ---------------------------------------------------------------------- */

.help { border-bottom: var(--hairline); }
.help:first-of-type { border-top: var(--hairline); }

.help__q {
  /* The native marker is tiny and inconsistent across browsers; a rotating
     chevron drawn here is a bigger target and looks the same everywhere. */
  list-style: none;
  position: relative;
  min-height: 44px;
  display: flex;
  align-items: center;
  padding: var(--s-3) var(--s-6) var(--s-3) 0;
  cursor: pointer;
  font-weight: 600;
  font-size: 0.9375rem;
}
.help__q::-webkit-details-marker { display: none; }

.help__q::after {
  content: '';
  position: absolute;
  right: var(--s-2);
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--accent-text);
  border-bottom: 2px solid var(--accent-text);
  transform: rotate(45deg);
  transition: transform .15s ease;
}
.help[open] .help__q::after { transform: rotate(-135deg); }

.help__q:hover { color: var(--accent-text); }

.help__a { padding: 0 var(--s-2) var(--s-4); }
.help__a p { margin-bottom: var(--s-2); font-size: 0.9375rem; color: var(--muted); }
.help__a p:last-child { margin-bottom: 0; }

/* Two links side by side under the admin masthead. */
.masthead .small a + a { margin-left: var(--s-4); }

.status--success { color: var(--accent-text); }
.status--error   { color: var(--danger); }
