/* ═══════════════════════════════════════════════════════════════
   HardBones — gemeinsames Design-System
   Quelle: hardbones-website/assets/css/hb-ui.css

   Wird von der Website, /lapcalc/ und /pacemetrics/ verwendet.
   Die Kopien in den beiden Unterordnern gleicht das Deploy-Skript
   ab und prüft sie — dort nicht bearbeiten.
   ═══════════════════════════════════════════════════════════════ */

:root {
  color-scheme: dark;

  /* ── Farben als RGB-Kanäle ────────────────────────────────────
     Ohne Farbfunktion, damit Tailwind seinen Deckkraft-Zusatz
     einsetzen kann: rgb(var(--hb-red-rgb) / <alpha-value>).
     Ein einfaches --hb-red: #e0272f liesse bg-hb-red/10 still auf
     Vollton umspringen. */
  --hb-bg-rgb:         22  23  26;
  --hb-card-rgb:       30  31  35;
  --hb-surface-rgb:    39  40  45;
  --hb-border-rgb:     46  47  53;
  --hb-text-rgb:      242 243 245;
  --hb-muted-rgb:     154 158 167;
  --hb-faint-rgb:      91  95 104;
  --hb-red-rgb:       224  39  47;
  --hb-red-dark-rgb:  181  31  38;
  --hb-teal-rgb:        5 215 202;
  --hb-teal-dark-rgb:   1 162 154;
  --hb-yellow-rgb:    200 200  50;

  /* ── Volltonfassungen für handgeschriebenes CSS ────────────── */
  --hb-bg:        rgb(var(--hb-bg-rgb));
  --hb-card:      rgb(var(--hb-card-rgb));
  --hb-surface:   rgb(var(--hb-surface-rgb));
  --hb-border:    rgb(var(--hb-border-rgb));
  --hb-text:      rgb(var(--hb-text-rgb));
  --hb-muted:     rgb(var(--hb-muted-rgb));
  --hb-faint:     rgb(var(--hb-faint-rgb));
  --hb-red:       rgb(var(--hb-red-rgb));
  --hb-red-dark:  rgb(var(--hb-red-dark-rgb));
  --hb-teal:      rgb(var(--hb-teal-rgb));
  --hb-teal-dark: rgb(var(--hb-teal-dark-rgb));
  --hb-yellow:    rgb(var(--hb-yellow-rgb));

  /* ── Schriften ────────────────────────────────────────────── */
  --hb-font-heading: 'Barlow Condensed', Inter, sans-serif;
  --hb-font-body:    Inter, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --hb-font-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;

  /* ── Form und Bewegung ────────────────────────────────────── */
  --hb-radius-sm: 7px;
  --hb-radius:   11px;
  --hb-radius-lg:16px;
  --hb-ease-out: cubic-bezier(0.23, 1, 0.32, 1);

  /* Kantenlaenge der Bildmarke. Eine Groesse fuer alle vier Oberflaechen:
     vorher 28px in der Kopfzeile, 32px in der Fusszeile, 48px in lapcalc,
     gar keine in Verwaltung und PaceMetrics. */
  --hb-logo: 32px;

  /* Der Schriftzug neben der Bildmarke. Die Marke allein zu vereinheitlichen
     genuegte nicht: Sie war ueberall 32px, der Schriftzug daneben aber 13px
     auf der Website und 23px in lapcalc. Das Gespann muss stimmen, nicht nur
     das Bild. */
  --hb-wortmarke:        20px;
  --hb-wortmarke-zusatz: 12px;
  --hb-wortmarke-abstand: .75rem;

  /* ── Abstände wachsen mit der Fensterbreite, statt in Stufen
        zu springen ─────────────────────────────────────────── */
  --hb-gutter: clamp(1rem, 3vw, 2.5rem);
  --hb-stack:  clamp(1rem, 2vw, 1.75rem);

  /* ── Breiten ──────────────────────────────────────────────── */
  --hb-width-wide: 1600px;   /* Datenseiten */
  --hb-width-text: 70ch;     /* Fliesstext */
}

/* ── Altnamen der bestehenden Anwendungen ───────────────────────
   Vorübergehend: lapcalc (892 Zeilen) und PaceMetrics (155 Zeilen)
   laufen damit unverändert weiter, während sie umgestellt werden.
   Dieser Block verschwindet, wenn Plan 3c und 3d durch sind. */
:root {
  /* PaceMetrics */
  --bg:       var(--hb-bg);
  --card:     var(--hb-card);
  --surface:  var(--hb-surface);
  --border:   var(--hb-border);
  --text:     var(--hb-text);
  --muted:    var(--hb-muted);
  --red:      var(--hb-red);
  --red-dark: var(--hb-red-dark);
  --teal:     var(--hb-teal);
  --yellow:   var(--hb-yellow);
  --ease-out: var(--hb-ease-out);

  /* lapcalc */
  --bg-base:       var(--hb-bg);
  --bg-card:       var(--hb-card);
  --bg-elevated:   var(--hb-surface);
  --border-soft:   var(--hb-border);
  --accent:        var(--hb-red);
  --accent-deep:   var(--hb-red-dark);
  --accent-2:      var(--hb-teal);
  --accent-2-deep: var(--hb-teal-dark);
  --accent-3:      var(--hb-yellow);
  --text-dim:      var(--hb-muted);
  --text-faint:    var(--hb-faint);
  --mono:          var(--hb-font-mono);
  --display:       var(--hb-font-heading);
  --body:          var(--hb-font-body);
  --radius-sm:     var(--hb-radius-sm);
  --radius:        var(--hb-radius);
  --radius-lg:     var(--hb-radius-lg);
}


/* Das Fundament bringt sein eigenes Box-Modell mit. Ohne das ergibt
   .hb-page (width: 100% plus Innenabstand) einen Ueberstand und die
   Seite scrollt seitlich. Alle drei Anwendungen setzen border-box
   heute selbst -- darauf darf sich eine gemeinsame Datei aber nicht
   verlassen. Aufgefallen auf der eigenstaendigen Musterseite. */
*,
*::before,
*::after { box-sizing: border-box; }


/* ═══════════════════════════════════════════════════════════════
   PRIMITIVE
   ═══════════════════════════════════════════════════════════════ */

.hb-page {
  margin-inline: auto;
  padding-inline: var(--hb-gutter);
  width: 100%;
}

/* Datenlastige Seiten dürfen breit werden, Fliesstext nicht.
   Ein einziger Deckel wäre für Tabellen zu eng und für Text zu weit. */
.hb-page--wide { max-width: var(--hb-width-wide); }
.hb-page--text { max-width: var(--hb-width-text); }

.hb-stack > * + * { margin-block-start: var(--hb-stack); }

.hb-cluster {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  align-items: center;
}

.hb-card {
  background: var(--hb-card);
  border: 1px solid var(--hb-border);
  border-radius: var(--hb-radius);
  padding: clamp(1rem, 2vw, 1.5rem);
}

/* Bewusst kein overflow-x auf .hb-card: Genau das liess in
   PaceMetrics die Tabellen in ihrer Karte scrollen, statt die
   verfügbare Breite zu nutzen. */

.hb-muted { color: var(--hb-muted); }
.hb-mono  { font-family: var(--hb-font-mono); font-variant-numeric: tabular-nums; }


/* ═══════════════════════════════════════════════════════════════
   TABELLE

   Oberhalb von 700px eine gewöhnliche Tabelle über die volle
   Breite ihres Containers — kein min-width, kein overflow.
   Darunter klappt jede Zeile zu einer Karte.

   Jede Zelle braucht dafür ein data-label mit der Spaltenüber-
   schrift. Fehlt es, zeigt die Karte nur den Wert ohne Bezeichnung.
   ═══════════════════════════════════════════════════════════════ */

.hb-table {
  width: 100%;
  border-collapse: collapse;
}

.hb-table th,
.hb-table td {
  padding: .55rem .65rem;
  text-align: left;
  border-bottom: 1px solid var(--hb-border);
}

.hb-table th {
  color: var(--hb-muted);
  font-weight: 600;
  font-size: .82rem;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.hb-table .num,
.hb-table th.num,
.hb-table td.num {
  text-align: right;
  font-family: var(--hb-font-mono);
  font-variant-numeric: tabular-nums;
}

.hb-table tbody tr:hover { background: var(--hb-surface); }

@media (max-width: 700px) {
  .hb-table,
  .hb-table tbody,
  .hb-table tr,
  .hb-table td { display: block; }

  .hb-table thead { display: none; }

  .hb-table tr {
    margin-bottom: .75rem;
    border: 1px solid var(--hb-border);
    border-radius: var(--hb-radius-sm);
    background: var(--hb-card);
  }

  .hb-table tbody tr:hover { background: var(--hb-card); }

  .hb-table td {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: .25rem 1rem;
    border-bottom: 1px solid var(--hb-border);

    /* Ohne das drücken Bezeichnung und Inhalt einander aus der Zelle,
       statt umzubrechen — die Seite scrollt dann seitlich. Aufgefallen an
       einer Fahrerliste in der PaceMetrics-Rennauswertung. */
    overflow-wrap: anywhere;
  }

  /* Der Inhalt darf schrumpfen, die Bezeichnung behält ihre Breite. */
  .hb-table td > * { min-width: 0; max-width: 100%; }

  .hb-table tr td:last-child { border-bottom: 0; }

  .hb-table td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    color: var(--hb-muted);
    font-size: .78rem;
    letter-spacing: .04em;
    text-transform: uppercase;
  }

  /* Eine Zelle ohne data-label behält die volle Breite, statt
     gegen einen leeren Platzhalter zu drücken. */
  .hb-table td:not([data-label])::before { display: none; }

  .hb-table .num,
  .hb-table td.num { text-align: right; }
}

/* Schlüssel-Wert-Tabellen sind bereits Paare und bleiben in beiden
   Grössen unverändert. */
.hb-table--kv th,
.hb-table--kv td { border: 0; padding: .2rem 0; }

@media (max-width: 700px) {
  .hb-table--kv,
  .hb-table--kv tbody,
  .hb-table--kv tr,
  .hb-table--kv td { display: revert; }

  .hb-table--kv tr { border: 0; background: none; margin: 0; }
  .hb-table--kv td::before { display: none; }
}


/* ═══════════════════════════════════════════════════════════════
   KOMPONENTEN
   ═══════════════════════════════════════════════════════════════ */

.hb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: .6rem 1.2rem;
  border: 0;
  border-radius: var(--hb-radius-sm);
  background: var(--hb-red);
  color: #fff;
  font: 600 .95rem var(--hb-font-body);
  cursor: pointer;
  text-decoration: none;
  transition: background .18s var(--hb-ease-out), transform .12s var(--hb-ease-out);
}
.hb-btn:hover  { background: var(--hb-red-dark); text-decoration: none; }
.hb-btn:active { transform: scale(.97); }

.hb-btn--quiet {
  background: var(--hb-surface);
  color: var(--hb-text);
  border: 1px solid var(--hb-border);
  padding: .4rem .9rem;
  font-size: .85rem;
}
.hb-btn--quiet:hover { background: var(--hb-border); }

.hb-field {
  width: 100%;
  padding: .6rem .75rem;
  background: rgb(var(--hb-surface-rgb) / .5);
  border: 1px solid var(--hb-border);
  border-radius: var(--hb-radius-sm);
  color: var(--hb-text);
  font: inherit;
}
.hb-field::placeholder { color: var(--hb-faint); }

.hb-label {
  display: block;
  margin-bottom: .3rem;
  color: var(--hb-muted);
  font-size: .8rem;
}

:where(.hb-field, .hb-btn, a, button, summary):focus-visible {
  outline: 2px solid var(--hb-teal);
  outline-offset: 2px;
}

.hb-notice {
  padding: .75rem 1rem;
  border: 1px solid var(--hb-border);
  border-radius: var(--hb-radius-sm);
  background: var(--hb-surface);
}
.hb-notice--error { border-color: rgb(var(--hb-red-rgb) / .5);  background: rgb(var(--hb-red-rgb) / .08); }
.hb-notice--ok    { border-color: rgb(var(--hb-teal-rgb) / .5); background: rgb(var(--hb-teal-rgb) / .08); }

/* ── Bildmarke ────────────────────────────────────────────────── */
/* Quadratisch: die Datei hat viewBox 0 0 1024 1024. Deshalb dieselbe
   Zahl fuer Breite und Hoehe, und flex-shrink aus, damit sie in engen
   Kopfzeilen nicht gequetscht wird. */
.hb-logo {
  width: var(--hb-logo);
  height: var(--hb-logo);
  flex-shrink: 0;
  transition: opacity .18s var(--hb-ease-out);
}

.hb-logo-link {
  display: inline-flex;
  align-items: center;
  gap: var(--hb-wortmarke-abstand);
}

.hb-logo-link:hover .hb-logo { opacity: .8; }

/* Fusszeile: zurueckhaltender als die Kopfzeile, aber dieselbe Groesse.
   Vorher unterschied sie sich in beidem. */
.hb-logo--gedaempft { opacity: .6; }
.hb-logo-link:hover .hb-logo--gedaempft { opacity: 1; }

/* ── Kopfzeile ────────────────────────────────────────────────── */

.hb-topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgb(var(--hb-bg-rgb) / .85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hb-border);
}

.hb-topbar__inner {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  min-height: 3.5rem;
  padding-block: .5rem;
}

.hb-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem;
}

.hb-nav a {
  color: var(--hb-muted);
  text-decoration: none;
  font-size: .9rem;
  transition: color .18s var(--hb-ease-out);
}
.hb-nav a:hover,
.hb-nav a[aria-current] { color: var(--hb-text); }

/* Menü ohne JavaScript: <details> klappt auf und zu, ist mit der
   Tastatur bedienbar und funktioniert bei abgeschaltetem Skript.
   Ein Menü, das ohne JavaScript nicht aufgeht, wäre ein Rückschritt
   gegenüber dem heutigen Zustand — dort steht die Navigation
   wenigstens im Quelltext, nur unsichtbar. */
.hb-menu { display: none; }
.hb-menu > summary {
  list-style: none;
  cursor: pointer;
  padding: .4rem .6rem;
  border: 1px solid var(--hb-border);
  border-radius: var(--hb-radius-sm);
  color: var(--hb-text);
}
.hb-menu > summary::-webkit-details-marker { display: none; }

/* Ohne diese Regel steht die Navigation auch im zugeklappten Zustand offen
   sichtbar in der Seite: .hb-nav setzt display:flex, und ein eigenes display
   auf dem Inhaltskind eines <details> hebt das Ausblenden durch den Browser
   auf. Das faellt nur unterhalb von 700px auf, wo das Menue ueberhaupt
   erscheint. */
.hb-menu:not([open]) > .hb-nav { display: none; }
.hb-menu[open] > .hb-nav {
  position: absolute;
  inset-inline: var(--hb-gutter);
  margin-top: .5rem;
  padding: 1rem;
  flex-direction: column;
  align-items: flex-start;
  gap: .9rem;
  background: var(--hb-card);
  border: 1px solid var(--hb-border);
  border-radius: var(--hb-radius);
}

@media (max-width: 700px) {
  .hb-topbar__nav { display: none; }
  .hb-menu        { display: block; margin-left: auto; }
}

/* ── Bewegung zurücknehmen ────────────────────────────────────────
   Wer im Betriebssystem "Bewegung reduzieren" gesetzt hat, meint es
   ernst: Für manche Menschen lösen bewegte Oberflächen Übelkeit oder
   Schwindel aus. Die Regel greift breit, weil die Animationen über
   drei Anwendungen und mehrere Dateien verteilt sind — eine Liste
   einzelner Klassen wäre nach dem nächsten Zusatz wieder unvollständig.

   .reveal steht ausdrücklich darin: Es beginnt bei opacity 0 und wird
   erst durch JavaScript sichtbar. Ohne diese Zeile bliebe der halbe
   Seiteninhalt unsichtbar, sobald das Skript nicht läuft. */
@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;
  }

  .reveal {
    opacity: 1;
    transform: none;
  }
}

/* ── Zeilenumbruch ────────────────────────────────────────────────
   balance verteilt die Wörter einer Überschrift gleichmässig auf ihre
   Zeilen, statt die letzte mit einem einzelnen Wort enden zu lassen.
   pretty tut dasselbe zurückhaltender für Fliesstext. Browser ohne
   Unterstützung ignorieren beides und brechen wie bisher um. */
h1,
h2,
h3,
.hb-title,
.header-brand {
  text-wrap: balance;
}

p,
.hb-lead {
  text-wrap: pretty;
}

/* ── Wortmarke ────────────────────────────────────────────────────
   Bildmarke plus Schriftzug als ein Gespann. Wer die Groesse aendern
   will, aendert --hb-wortmarke in :root, nicht diese Regeln. */
.hb-wortmarke {
  display: flex;
  flex-direction: column;
  line-height: 1;
  gap: 2px;
}

.hb-wortmarke__name {
  font-family: var(--hb-font-heading);
  font-weight: 900;
  font-size: var(--hb-wortmarke);
  letter-spacing: -0.01em;
  color: var(--hb-text);
}

.hb-wortmarke__zusatz {
  font-family: var(--hb-font-heading);
  font-weight: 900;
  font-size: var(--hb-wortmarke-zusatz);
  letter-spacing: 0.09em;
  color: var(--hb-text);
}

.hb-wortmarke__akzent { color: var(--hb-red); }

/* ── Produktmarke ─────────────────────────────────────────────────
   Für die Werkzeuge unter der Marke: Bildmarke plus Produktname in
   Versalien und Akzentfarbe, einzeilig. lapcalc und PaceMetrics
   tragen damit dasselbe Gespann und unterscheiden sich nur im Wort.

   Die Website selbst behält ihre zweizeilige Wortmarke: Sie ist die
   Marke, nicht eines ihrer Werkzeuge. Der Unterschied ist gewollt
   und trägt die Hierarchie.

   Die Grösse kommt aus --hb-wortmarke, dieselbe Zahl wie dort. */
.hb-produktmarke {
  font-family: var(--hb-font-heading);
  font-weight: 900;
  font-size: var(--hb-wortmarke);
  letter-spacing: 0.01em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--hb-red);
}
