/* ==========================================================================
   HFP — shared components
   Built entirely on tokens.css. Loaded after it, before any page CSS.
   DESIGN.md §8.
   ========================================================================== */

/* ---------- Button ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 44px; padding: 0 var(--sp-4);
  font-family: var(--font-sans); font-size: var(--fs-body); font-weight: 600; line-height: 1;
  color: var(--fg); background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--r-md);
  cursor: pointer; white-space: nowrap;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.btn:hover { background: var(--surface-3); border-color: var(--border-strong); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: var(--ring); outline-offset: var(--ring-offset); }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.45; pointer-events: none; }

.btn--primary { background: var(--accent-strong); border-color: transparent; color: var(--accent-fg); }
.btn--primary:hover { background: var(--accent-strong); filter: brightness(1.08); }
.btn--ghost { background: transparent; border-color: transparent; color: var(--fg-2); }
.btn--ghost:hover { background: var(--surface-2); color: var(--fg); }
.btn--danger { color: var(--danger); border-color: color-mix(in oklab, var(--danger) 40%, var(--border)); }
.btn--danger:hover { background: var(--danger-soft); }
.btn--block { width: 100%; }

/* Small variants. The 44px hit area is BAKED IN, not left to whoever remembers
   the .hit-44 utility — that is the failure mode this rule exists to prevent.
   .hit-44 stays for one-offs (.fav-btn, row actions in the gear/injury lists). */
.btn--sm {
  position: relative;
  min-height: 32px; padding: 0 var(--sp-3); font-size: var(--fs-sm);
}
.btn--sm::before {
  content: ""; position: absolute; inset: 50% auto auto 50%;
  translate: -50% -50%; min-width: 44px; min-height: 44px;
}
.btn--lg { min-height: 48px; padding: 0 var(--sp-6); font-size: var(--fs-lg); }
.btn-icon { width: 44px; height: 44px; min-height: 0; padding: 0; }

/* ---------- Field ---------- */
.field {
  width: 100%; height: 44px; padding: 0 var(--sp-3);
  font-family: var(--font-sans); font-size: var(--fs-input); font-weight: 400; line-height: 1;
  color: var(--fg); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-md);
  transition: border-color var(--dur-1) var(--ease);
}
.field::placeholder { color: var(--fg-3); }
.field:hover { border-color: var(--border-strong); }
.field:focus-visible { border-color: var(--accent); outline: var(--ring); outline-offset: var(--ring-offset); }

.label {
  display: block; margin-bottom: var(--sp-1);
  font-size: var(--fs-label); font-weight: 600; color: var(--fg-2);
}

.field-wrap { position: relative; display: flex; align-items: center; }
.field-wrap > .icon { position: absolute; left: var(--sp-3); color: var(--fg-3); pointer-events: none; }
.field-wrap > .field { padding-left: calc(var(--sp-3) + 20px + var(--sp-2)); }

/* ---------- Chip / badge ---------- */
.chip {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  height: 26px; padding: 0 var(--sp-2);
  font-size: var(--fs-label); font-weight: 500; line-height: 1; white-space: nowrap;
  color: var(--fg-2); background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--r-sm);
}
.chip--num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.chip--filter {
  position: relative;
  height: 32px; padding: 0 var(--sp-3); border-radius: var(--r-full);
  cursor: pointer; font-family: inherit;
}
.chip--filter::before {
  content: ""; position: absolute; inset: 50% auto auto 50%;
  translate: -50% -50%; min-width: 100%; min-height: 44px;
}
.chip--filter[aria-pressed="true"] {
  background: var(--accent-soft); color: var(--accent);
  border-color: color-mix(in oklab, var(--accent) 40%, transparent);
}

.badge {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  height: 22px; padding: 0 var(--sp-2);
  font-size: var(--fs-caption); font-weight: 700; font-stretch: var(--wdth-display);
  letter-spacing: var(--tr-wide); text-transform: uppercase; line-height: 1;
  /* Fixed height + the longest real status („Skráning opin") = a two-line
     wrap that overflows the pill. The label never wraps; the row lets it
     take the width it needs. */
  white-space: nowrap;
  border-radius: var(--r-sm);
}
.badge--open   { background: var(--trail-soft);  color: var(--trail);  }
.badge--conf   { background: var(--surface-2);   color: var(--fg-2);   }
.badge--unconf { background: var(--road-soft);   color: var(--road);   }
.badge--cancel { background: var(--danger-soft); color: var(--danger); }
.badge--past   { background: var(--surface-2);   color: var(--fg-2);   }

/* ---------- Segmented ---------- */
.seg {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-md);
}
.seg button {
  position: relative;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  min-height: 34px; padding: 0 var(--sp-3);
  font-family: inherit; font-size: var(--fs-sm); font-weight: 600; line-height: 1;
  color: var(--fg-2); background: transparent; border: 0; border-radius: 7px;
  cursor: pointer;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
/* 34px visual, 44px target. Full width rather than 44px wide, so adjacent
   segments don't overlap each other's hit areas and steal taps at the seam.
   The segmented control is the primary filter on mobile — it has to be
   thumb-sized. */
.seg button::before {
  content: ""; position: absolute; inset: 50% auto auto 50%;
  translate: -50% -50%; min-width: 100%; min-height: 44px;
}
.seg button:hover { color: var(--fg); }
.seg button[aria-pressed="true"] { background: var(--surface); color: var(--fg); box-shadow: var(--shadow-1); }
.seg button:focus-visible { outline: var(--ring); outline-offset: -1px; }

/* ---------- Card / tile ---------- */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--sp-4);
}

.tile {
  display: flex; flex-direction: column; gap: var(--sp-1);
  padding: var(--sp-4);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
}
.tile__k {
  font-size: var(--fs-caption); font-weight: 700; font-stretch: var(--wdth-eyebrow);
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--fg-3);
}
.tile__v {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-h2); font-weight: 700; line-height: 1;
  letter-spacing: var(--tr-tight); color: var(--fg);
}
.tile__v small { margin-left: 2px; font-size: var(--fs-body); font-weight: 500; color: var(--fg-2); }
.tile__sub { font-size: var(--fs-sm); color: var(--fg-2); }

/* ---------- Race row (the calendar's atom) ---------- */
.race-row {
  display: grid; position: relative;
  grid-template-columns: 3px 56px 1fr auto auto;
  align-items: center; gap: var(--sp-3);
  width: 100%; padding: var(--sp-3) var(--sp-4) var(--sp-3) 0;
  font: inherit; color: var(--fg); text-align: left;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden;
  transition: border-color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease);
}
.race-row:hover { border-color: var(--border-strong); box-shadow: var(--shadow-1); }
/* The row's own click/focus target: a real button stretched over the whole row
   (position:relative above is what it sizes against), so every cell except the
   star opens the race — a `<button>` cannot legally CONTAIN another interactive
   element, which ruled out .race-row itself being the button while .fav-btn sat
   inside it (that used to be a role="button" span; browsers disagreed on whether
   its Enter/Space even worked). outline-offset is negative because .race-row
   clips overflow — a positive (outward) ring would be cut off on every edge. */
.race-row__hit {
  position: absolute; inset: 0; z-index: 0;
  margin: 0; padding: 0; border: 0; background: none; cursor: pointer;
}
.race-row__hit:focus-visible { outline: var(--ring); outline-offset: -2px; }

.race-row__rail { align-self: stretch; background: var(--cat, var(--fg-3)); }
.race-row[data-type="trail"] { --cat: var(--trail); }
.race-row[data-type="road"]  { --cat: var(--road); }
.race-row[data-type="other"] { --cat: var(--other); }

.race-row__date { text-align: center; font-family: var(--font-mono); line-height: 1.05; }
.race-row__date b { display: block; font-size: var(--fs-h3); font-weight: 700; }
.race-row__date span {
  font-family: var(--font-sans); font-size: var(--fs-caption); font-weight: 700; font-stretch: var(--wdth-display);
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--fg-3);
}
.race-row__title { font-size: var(--fs-lg); font-weight: 600; letter-spacing: var(--tr-tight); }
.race-row__meta { font-size: var(--fs-sm); color: var(--fg-2); }
/* The name and location column (.race-row__main) is the only one allowed to shrink.
   Without min-width:0 a long Icelandic place name forces the row wider than its grid. */
.race-row__main { min-width: 0; }
.race-row__dist {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--fs-body); color: var(--fg);
}
@media (max-width: 520px) {
  .race-row { grid-template-columns: 3px 48px 1fr auto; row-gap: var(--sp-1); }
  .race-row__dist { grid-column: 3 / -1; }
}

/* ---------- Month divider ---------- */
.month-head {
  position: sticky; top: var(--header-h); z-index: var(--z-sticky);
  display: flex; align-items: baseline; gap: var(--sp-3);
  padding: var(--sp-4) 0 var(--sp-2);
  font-size: var(--fs-label); font-weight: 700; font-stretch: var(--wdth-eyebrow);
  letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--fg-3);
  background: linear-gradient(var(--bg) 65%, transparent);
}
.month-head::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* ---------- Sheet / scrim ---------- */
.scrim {
  position: fixed; inset: 0; z-index: var(--z-overlay);
  background: var(--scrim);
  backdrop-filter: blur(3px);
  opacity: 0; transition: opacity var(--dur-2) var(--ease);
}
.scrim[data-open] { opacity: 1; }

.sheet {
  position: fixed; z-index: var(--z-modal);
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: var(--shadow-3); overscroll-behavior: contain;
}
@media (min-width: 768px) {
  .sheet--side {
    inset: 0 0 0 auto; width: min(720px, 92vw);
    border-radius: var(--r-xl) 0 0 var(--r-xl);
    transform: translateX(100%);
    transition: transform var(--dur-3) var(--ease-out);
  }
}
@media (max-width: 767px) {
  .sheet--side {
    inset: auto 0 0 0; height: 92dvh;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    transform: translateY(100%);
    transition: transform var(--dur-3) var(--ease-out);
  }
}
.sheet--side[data-open] { transform: none; }
.sheet--center {
  inset: 50% auto auto 50%; translate: -50% -50%;
  width: min(560px, calc(100vw - var(--sp-8)));
  max-height: 85dvh; border-radius: var(--r-xl);
}

/* ---------- States ---------- */
.skel {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%);
  background-size: 400% 100%;
  border-radius: var(--r-sm);
  animation: hfp-shimmer 1.4s ease infinite;
}
@keyframes hfp-shimmer { to { background-position: -135% 0; } }

.empty {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-3);
  padding: var(--sp-16) var(--sp-5); text-align: center;
}
.empty h3 { font-size: var(--fs-h3); }
.empty p { max-width: 44ch; color: var(--fg-2); }

.notice {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-sm); color: var(--fg-2);
  background: var(--surface-2); border-bottom: 1px solid var(--border);
}
.notice--warn { color: var(--warn); background: var(--warn-soft); }
.notice--danger { color: var(--danger); background: var(--danger-soft); }

.msg {
  margin-top: var(--sp-4); padding: var(--sp-3);
  font-size: var(--fs-sm); line-height: var(--lh-snug);
  border-radius: var(--r-md);
}
.msg:empty { display: none; }
.msg[data-tone="err"] { background: var(--danger-soft); color: var(--danger); }
/* --trail-ink, not --trail: green on its own 10% tint measured 4,25:1 at 13px on the login page,
   under §11's 4,5 floor. The ink token exists for exactly this and now lives in tokens.css, which
   this file's pages DO load — it used to be declared in styles.css, which they do not. */
.msg[data-tone="ok"]  { background: var(--trail-soft);  color: var(--trail-ink); }

/* ---------- Toast ---------- */
.toast-stack {
  position: fixed; z-index: var(--z-toast);
  inset: auto var(--sp-4) calc(var(--sp-4) + env(safe-area-inset-bottom)) auto;
  display: flex; flex-direction: column; gap: var(--sp-2);
}
@media (max-width: 767px) { .toast-stack { inset: auto var(--sp-4) calc(var(--tabbar-h) + var(--sp-4) + env(safe-area-inset-bottom)) var(--sp-4); } }
.toast {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--border-strong); border-radius: var(--r-md);
  box-shadow: var(--shadow-2);
  animation: hfp-toast-in var(--dur-3) var(--ease-out);
}
/* --warn, not --road: this is a toast's CAUTION tone, not a race type — §4.1 rule 2
   reserves --road for race type only. Matches .notice--warn just above, which already
   gets this right: --warn needs no -ink correction on its own -soft tint (unlike
   trail/road/other), so this is the token itself, not a derived variant. */
.toast--warn { border-color: color-mix(in srgb, var(--warn) 40%, var(--border-strong)); color: var(--warn); }
@keyframes hfp-toast-in { from { opacity: 0; transform: translateY(8px); } }

/* ---------- Layout helpers ---------- */
.shell { max-width: var(--w-content); margin-inline: auto; padding-inline: clamp(var(--sp-4), 4vw, var(--sp-10)); }
.stack { display: flex; flex-direction: column; gap: var(--sp-4); }
.row { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.list { display: flex; flex-direction: column; gap: var(--sp-3); max-width: var(--w-list); }
.grid-cards { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); }
.grid-tiles { display: grid; gap: var(--sp-2); grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
