/* ============================================================
   Kontrollschild-Renderer

   Masse nach den offiziellen Schweizer Formaten:
     auto-long   500 x 110 mm   (Frontschild / lange Variante)
     auto-short  300 x 160 mm   (hohe Variante, Heck)
     moto        180 x 140 mm   (Motorrad, zweizeilig)
     moped       100 x 140 mm   (Kleinmotorrad, zweizeilig schmal)

   Alle Groessen leiten sich aus --ks-h (Hoehe) ab, damit ein Schild
   ueberall konsistent skaliert. Breite kommt aus aspect-ratio.
   ============================================================ */

@font-face {
  font-family: 'SwissLicensePlates';
  src: url('/static/fonts/SwissLicensePlates.ttf') format('truetype');
  font-display: swap;
  /* Die Schrift deckt nur 0-9, A-Z, Punkt und Leerzeichen ab. */
  unicode-range: U+0020, U+002E, U+0030-0039, U+0041-005A;
}

.ks {
  --ks-h: 46px;
  --ks-radius: calc(var(--ks-h) * 0.09);
  --ks-border: max(1px, calc(var(--ks-h) * 0.035));

  display: inline-flex;
  align-items: center;
  height: var(--ks-h);
  box-sizing: border-box;
  background: #fff;
  color: #111;
  border: var(--ks-border) solid #1a1a1a;
  border-radius: var(--ks-radius);
  padding: 0 calc(var(--ks-h) * 0.08);
  gap: calc(var(--ks-h) * 0.07);
  font-family: 'SwissLicensePlates', 'Arial Narrow', Arial, sans-serif;
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  user-select: none;
  /* Leichte Plastik-Anmutung, kein Schlagschatten-Kitsch. */
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.6);
}

/* --- Formate ------------------------------------------------ */

.ks--auto-long   { aspect-ratio: 500 / 110; }
.ks--auto-short  { aspect-ratio: 300 / 160; }
.ks--moto        { aspect-ratio: 180 / 140; }
.ks--moped       { aspect-ratio: 100 / 140; }

/* --- Einzeilig (Auto lang) ---------------------------------- */

.ks__text {
  font-size: calc(var(--ks-h) * 0.62);
  letter-spacing: calc(var(--ks-h) * 0.015);
  flex: 1 1 auto;
  text-align: center;
}

/* --- Hoheitszeichen ----------------------------------------- */

.ks__emblem {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(var(--ks-h) * 0.03);
}

.ks__emblem img,
.ks__emblem svg {
  display: block;
  width: calc(var(--ks-h) * 0.42);
  height: calc(var(--ks-h) * 0.42);
}

/* Fallback, solange kein Wappenbild hinterlegt ist: das Kantonskuerzel
   in kleiner Schrift statt eines leeren Kastens. */
.ks__emblem-fallback {
  width: calc(var(--ks-h) * 0.42);
  height: calc(var(--ks-h) * 0.42);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #bbb;
  border-radius: 2px;
  font-size: calc(var(--ks-h) * 0.2);
  color: #555;
  background: #f5f5f5;
}

.ks__emblem-label {
  font-size: calc(var(--ks-h) * 0.17);
  letter-spacing: 0.03em;
  color: #333;
}

/* --- Zweizeilig (Motorrad, Moped) --------------------------- */

.ks--moto,
.ks--moped {
  flex-direction: column;
  justify-content: center;
  gap: 0;
  padding: calc(var(--ks-h) * 0.06) calc(var(--ks-h) * 0.05);
}

.ks--moto .ks__row-top,
.ks--moped .ks__row-top {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--ks-h) * 0.08);
  width: 100%;
  height: 38%;
}

.ks--moto .ks__row-bottom,
.ks--moped .ks__row-bottom {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 62%;
}

.ks--moto .ks__kanton,
.ks--moped .ks__kanton {
  font-size: calc(var(--ks-h) * 0.24);
  letter-spacing: 0.04em;
}

.ks--moto .ks__number,
.ks--moped .ks__number {
  font-size: calc(var(--ks-h) * 0.46);
  letter-spacing: calc(var(--ks-h) * 0.01);
}

.ks--moto .ks__emblem img,
.ks--moto .ks__emblem svg,
.ks--moped .ks__emblem img,
.ks--moped .ks__emblem svg,
.ks--moto .ks__emblem-fallback,
.ks--moped .ks__emblem-fallback {
  width: calc(var(--ks-h) * 0.24);
  height: calc(var(--ks-h) * 0.24);
}

/* --- Zustandsvarianten -------------------------------------- */

/* Nicht mehr verfuegbar / verkauft: ausgegraut. */
.ks--muted { opacity: 0.55; filter: grayscale(0.7); }

/* Hervorhebung fuer POI / Favoriten: goldener Rahmen plus wandernder
   Glanzstreifen.
   Der Rahmen ist bewusst STATISCH. Ein animierter box-shadow erzeugt bei
   jedem Frame ein Repaint der ganzen Flaeche; auf iOS Safari kostete das
   nicht nur Leistung, sondern brachte den Glanzstreifen daneben zum
   Stocken. */
.ks--poi {
  position: relative;
  box-shadow:
    0 0 0 2px #d4a017,
    0 0 12px rgba(200, 150, 27, 0.45),
    inset 0 0 0 1px rgba(255, 255, 255, 0.6);
  /* Eigene Compositing-Ebene: verhindert Flackern beim Zusammenspiel von
     border-radius, overflow:hidden und animiertem Kind auf iOS. */
  transform: translateZ(0);
  isolation: isolate;
}

/* Der Glanz ist ein ECHTES Element (siehe partials/plate.ejs), kein
   ::after. Animierte Pseudoelemente in geklippten Flex-Containern werden
   auf iOS Safari unzuverlaessig gerendert; ein normales span nicht. */
.ks__shine {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 55%;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    105deg,
    rgba(255, 255, 255, 0) 20%,
    rgba(255, 255, 255, 0.55) 45%,
    rgba(255, 255, 255, 0.85) 50%,
    rgba(255, 255, 255, 0.55) 55%,
    rgba(255, 255, 255, 0) 80%
  );
  /* translate3d statt translateX: erzwingt Hardware-Compositing, damit
     iOS die Ebene tatsaechlich pro Frame neu zeichnet. */
  transform: translate3d(-130%, 0, 0);
  will-change: transform;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  animation: ks-shine 3.4s ease-in-out infinite;
}

@keyframes ks-shine {
  0%   { transform: translate3d(-130%, 0, 0); }
  /* Lange Pause zwischen den Durchläufen - sonst wirkt es unruhig. */
  55%  { transform: translate3d(300%, 0, 0); }
  100% { transform: translate3d(300%, 0, 0); }
}

/* Landwirtschaft/Spezial: gelber Grund (fuer spaeter). */
.ks--yellow { background: #f5c518; }

/* --- Horizontaler Scroller ---------------------------------- */

.ks-scroller {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 4px 2px 14px;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.ks-scroller::-webkit-scrollbar { height: 8px; }
.ks-scroller::-webkit-scrollbar-thumb { background: rgba(0,0,0,.2); border-radius: 4px; }
.ks-scroller::-webkit-scrollbar-track { background: transparent; }

.ks-card {
  flex: 0 0 auto;
  scroll-snap-align: start;
  background: #fff;
  border-radius: 10px;
  padding: 12px 14px 10px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.10);
  text-decoration: none;
  color: inherit;
  transition: box-shadow .15s, transform .15s;
}

.ks-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,.14); transform: translateY(-1px); }

.ks-card__meta {
  margin-top: 8px;
  font-size: 0.82rem;
  color: rgba(0, 0, 0, 0.55);
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.ks-card__price { font-weight: 600; color: #2e7d32; }

/* Wischhinweis nur dort, wo Scrollen noetig ist. */
.ks-scroller-wrap { position: relative; }
.ks-scroller-wrap::after {
  content: '';
  position: absolute;
  top: 0; right: 0; bottom: 14px;
  width: 28px;
  background: linear-gradient(to right, rgba(250,250,250,0), rgba(250,250,250,.95));
  pointer-events: none;
  opacity: 0;
  transition: opacity .2s;
}
.ks-scroller-wrap.is-scrollable::after { opacity: 1; }

/* ------------------------------------------------------------------
   Werbetafel: endlos nach links laufender Streifen.

   Der Track enthaelt die Schilder ZWEIMAL. Die Animation verschiebt ihn
   um genau -50%, also um eine volle Kopie - dadurch ist der Sprung
   zurueck auf 0 unsichtbar und der Lauf wirkt endlos.

   Die Dauer setzt JS als --ks-marquee-duration, abgeleitet aus der
   tatsaechlichen Breite. So bleibt die Geschwindigkeit gleich, egal wie
   viele Schilder drin sind.
   ------------------------------------------------------------------ */
.ks-marquee {
  position: relative;
  overflow: hidden;
  padding: 6px 0 10px;
}

/* Weiche Kanten links und rechts.
   Bewusst als Farbverlauf-Overlays statt per `mask-image`: eine Maske
   erzeugt auf iOS Safari eine eigene Compositing-Ebene, in der
   Animationen von Kindelementen einmal gerastert und dann nicht mehr
   aktualisiert werden - der Glanzeffekt auf den POI-Schildern stand
   dadurch still. Overlays haben diesen Nebeneffekt nicht. */
.ks-marquee::before,
.ks-marquee::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 46px;
  z-index: 2;
  pointer-events: none;
}

.ks-marquee::before {
  left: 0;
  background: linear-gradient(to right, var(--c-bg, #f2f3f5), rgba(242, 243, 245, 0));
}

.ks-marquee::after {
  right: 0;
  background: linear-gradient(to left, var(--c-bg, #f2f3f5), rgba(242, 243, 245, 0));
}

.ks-marquee__track {
  --ks-marquee-duration: 60s;
  display: flex;
  width: max-content;
  animation: ks-marquee-scroll var(--ks-marquee-duration) linear infinite;
  will-change: transform;
}

/* Abstand als margin an den Karten, NICHT als flex-gap.
   Mit `gap` waere die halbe Track-Breite nicht exakt eine Kopie: bei n
   Elementen gibt es n-1 Zwischenraeume, die Haelfte trifft also mitten in
   einen Zwischenraum und der Streifen ruckt bei jeder Runde um ein halbes
   Gap. Als margin gehoert der Abstand zum Element und die Rechnung stimmt. */
.ks-marquee__track > .ks-card { margin-right: 14px; }

@keyframes ks-marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Anhalten, solange man hinsieht oder etwas anfassen will. */
.ks-marquee:hover .ks-marquee__track,
.ks-marquee:focus-within .ks-marquee__track,
.ks-marquee.is-paused .ks-marquee__track {
  animation-play-state: paused;
}

/* Passt der Inhalt ohne Ueberlauf, waere ein Lauf sinnlos - JS setzt das. */
.ks-marquee.is-static .ks-marquee__track {
  animation: none;
  width: auto;
  flex-wrap: nowrap;
}

.ks-marquee__hint {
  font-size: 0.78rem;
  color: rgba(0, 0, 0, 0.45);
  margin-top: 2px;
}

/* Wer Animationen abgestellt hat, bekommt einen normalen Scrollstreifen. */
@media (prefers-reduced-motion: reduce) {
  .ks-marquee { overflow-x: auto; }
  .ks-marquee__track { animation: none; }
  .ks__shine { animation: none; opacity: 0; }
}

@media (max-width: 700px) {
  .ks-scroller { gap: 10px; padding-bottom: 12px; }
  .ks-card { padding: 10px 12px 8px; }
  .ks-marquee__track > .ks-card { margin-right: 10px; }
}

/* ==================================================================
   Kontrollschild als Bild (swiss-plate-renderer)

   Loest die schriftbasierte .ks-Darstellung in den Listen ab: echte
   Kantonswappen, normgerechte Masse, ein <img> statt eines Dutzends
   verschachtelter Spans.
   ================================================================== */
.ks-img {
  display: inline-block;
  vertical-align: middle;
  width: auto;          /* Hoehe steuert, Breite folgt dem Seitenverhaeltnis */
  max-width: 100%;
  border-radius: 2px;
}

/* Nicht mehr verfuegbar: zurueckgenommen, aber lesbar. */
.ks-img--muted {
  opacity: .45;
  filter: grayscale(1);
}

/* Hervorgehoben (POI / Favorit). Statischer Schein - eine animierte
   box-shadow laesst iOS Safari bei jedem Frame neu zeichnen. */
.ks-img--poi {
  box-shadow: 0 0 0 2px #f7c948, 0 0 12px rgba(247, 201, 72, .55);
}

.ks-img-link {
  display: inline-block;
  line-height: 0;       /* kein Zeilenabstand unter dem Bild */
}

.ks-img-fallback {
  font-weight: 600;
  letter-spacing: .02em;
}

/* In den Kartenansichten auf kleinen Schirmen darf das Schild die volle
   Breite nutzen - dort ist es der Titel der Karte. */
@media (max-width: 700px) {
  .data-table td.card-title-cell .ks-img { height: 46px !important; }

  /* Zweizeilige Schilder (Motorrad 180x140, Mofa 100x140) brauchen mehr
     Hoehe fuer dieselbe Ziffergroesse. Erkennbar am width-Attribut, das
     der Partial aus den Normmassen schreibt. */
  .data-table td.card-title-cell .ks-img[width="180"],
  .data-table td.card-title-cell .ks-img[width="100"] { height: 66px !important; }
}
