/* ==========================================================================
   FAHRSCHULEN — the directory page (/fahrschulen)
   ==========================================================================
   After /legal.css (hero, light), /help.css (the search field, the chips),
   /school.css (the disclosure, map-pin and star) and /school-card.css (the
   card itself). This file is the page around the cards: the sticky toolbar
   with class chips and sort, the list, the empty state and the closing
   "Ihre Fahrschule fehlt hier?". Prefix `sd-`.

   Calm on purpose: black surfaces, white as the one strong colour, and the
   only movement is the cards arriving once and gliding to a new place when
   the order changes, and the chip row on a phone scrolling the chosen class
   into view (js/fahrschulen.js). Everything else changes in place.
   ========================================================================== */

[data-i="locate-fixed"] { --m: url("/app/vendor/lucide/locate-fixed.svg"); }
[data-i="search-x"] { --m: url("/app/vendor/lucide/search-x.svg"); }
[data-i="rotate-ccw"] { --m: url("/app/vendor/lucide/rotate-ccw.svg"); }

.sd-search { view-transition-name: fahrschul-suche; }            /* the landing teaser's field morphs into this one (C.10) */
.sd-trust { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 18px; margin-top: 18px; color: var(--ink-faint); font-size: var(--t-base); }
.sd-trust span { display: inline-flex; align-items: center; gap: 8px; }
.sd-trust .ln-i { --ln-i: 14px; }
.sd-wrap { width: min(100% - var(--ln-gut) * 2, var(--ln-max)); margin: 0 auto; }
.sd-sentinel { display: block; height: 1px; }
.sd-bar { position: sticky; top: var(--ln-header); z-index: 5; display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px 24px; padding: 14px 0; border-bottom: 1px solid transparent; background: var(--canvas); transition: border-color var(--d-slow) ease; }
.sd-bar.is-stuck { border-bottom-color: var(--line); }
.sd-chips { flex: 1 1 0; min-width: min(100%, 420px); justify-content: flex-start; margin: 0; }
.sd-chips a { padding: 0 13px; font-variant-numeric: tabular-nums; transition: border-color var(--d-fast) ease, color var(--d-fast) ease, background var(--d-fast) ease, transform var(--d-press) var(--ease-out); }

/* Sort is one control with three positions, not three more chips: the
   filter above says WHICH schools, this says in what order. */
.sd-sort { display: inline-flex; flex: none; gap: 2px; padding: 2px; border: 1px solid var(--line); border-radius: 999px; }
.sd-sort a, .sd-sort button { display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 28px; padding: 0 13px; border: 0; border-radius: 999px; background: transparent; color: var(--ink-muted); font: inherit; font-size: var(--t-base); font-weight: var(--w-medium); white-space: nowrap; cursor: pointer; transition: color var(--d-fast) ease, background var(--d-fast) ease, transform var(--d-press) var(--ease-out); }
.sd-sort .ln-i { --ln-i: 14px; }
.sd-sort button[aria-busy="true"] { cursor: progress; }
.sd-sort button[aria-busy="true"] .ln-i { animation: sd-locate 1.2s ease-in-out infinite; }
@keyframes sd-locate { 50% { opacity: .35; } }
.sd-chips a[aria-current="true"], .sd-sort [aria-current="true"], .sd-sort [aria-pressed="true"] { border-color: var(--ink); background: var(--ink); color: var(--canvas); } /* = .pg-tabs current, legal.css:98 */
.sd-chips a:active, .sd-sort a:active, .sd-sort button:active { transform: scale(.97); }

/* What the list shows right now — the count, and why it is in this order. */
.sd-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; margin-top: 18px; }
.sd-count { color: var(--ink-muted); font-size: var(--t-md); font-weight: var(--w-medium); font-variant-numeric: tabular-nums; }
.sd-note { color: var(--ink-faint); font-size: var(--t-base); }
.sd-note:empty { display: none; }
.js .sd-note-klasse { display: none; } /* without JS only: the script shows the chosen chip itself (js/fahrschulen.js) */
.sd-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); gap: 12px; margin: 14px 0 0; padding: 0; list-style: none; }
/* content-visibility keeps a long list cheap, but it also contains paint:
   nothing may draw outside the <li>. The 4 px of padding (given back by the
   margin) are the room for the card's focus ring and its hover lift. */
.sd-item { content-visibility: auto; contain-intrinsic-size: auto 158px; margin: -4px; padding: 4px; }
.sd-item[hidden], .sd-empty[hidden] { display: none; }          /* a display rule would otherwise beat [hidden] (help.css:85) */
/* The cards arrive once, with the page (keyframes: landing.css:216). After
   that the list is "settled" (js/fahrschulen.js), so a card that moves or
   comes back from a filter does not play the entrance again. */
.js .sd-list:not(.is-settled) > .sd-item { animation: ln-enter 600ms var(--ease-out) both; animation-delay: calc(min(var(--i), 12) * 40ms); }
.sd-empty { display: grid; justify-items: center; gap: 14px; padding: 72px 0; color: var(--ink-muted); text-align: center; }
.sd-empty > p { max-width: 52ch; line-height: 1.6; }
.sd-empty > p strong { display: block; margin-bottom: 4px; font-size: 17px; font-weight: var(--w-semi); letter-spacing: -0.01em; }
.sd-empty .ln-i { --ln-i: 28px; color: var(--ink-faint); }
.sd-empty .btn .ln-i { --ln-i: 15px; color: inherit; }
.sd-empty strong { color: var(--ink); }
.sd-disclosure { max-width: 80ch; margin-top: 48px; }
.sd-own { position: relative; margin-top: 96px; padding: 64px 32px; overflow: hidden; border: 1px solid var(--line-strong); border-radius: var(--r-lg); background: var(--surface); text-align: center; }
.sd-own > * { position: relative; }
.sd-own > .ln-closing-glow { position: absolute; }
.sd-own > p { max-width: 58ch; margin: 16px auto 0; color: var(--ink-muted); font-size: 17px; line-height: 1.6; }
.sd-own .ln-cta { justify-content: center; margin-top: 28px; }
@media (hover: hover) and (pointer: fine) {
  .sd-sort a:not([aria-current="true"]):hover, .sd-sort button:not([aria-pressed="true"]):hover { background: var(--surface-hover); color: var(--ink); }
  .sd-chips a:not([aria-current="true"]):hover { border-color: var(--line-strong); color: var(--ink); }
}
/* Below the width where all classes fit in one line: one row that scrolls
   inside itself, edge to edge, instead of two or three rows of chips in a
   bar that stays on screen. */
@media (max-width: 960px) {
  .sd-bar { gap: 10px; padding: 10px 0; }
  .sd-chips { flex: 0 0 calc(100% + var(--ln-gut) * 2); min-width: 0; flex-wrap: nowrap; margin: -5px calc(var(--ln-gut) * -1); padding: 5px 40px 5px var(--ln-gut); /* 5 px: room for the focus ring and the hit area inside the scroller; 40 px at the end: the last chip can scroll clear of the fade below */ overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; scroll-padding-inline: var(--ln-gut); }
  /* Chips that run past an edge fade out, so the row reads as "more to the
     right" (as the header strip, landing.css). The left fade stays inside
     the gutter: at the start no chip is dimmed. js/fahrschulen.js keeps the
     chosen chip clear of both fades. */
  .sd-chips { -webkit-mask-image: linear-gradient(90deg, transparent, #000 12px, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(90deg, transparent, #000 12px, #000 calc(100% - 40px), transparent); }
  .sd-chips::-webkit-scrollbar { display: none; }
  .sd-chips a { position: relative; flex: none; }
  /* 44 px to hit, the same 34 px to see: the chip's 8 px gap is split.
     The inset counts from inside the 1 px border, so 6 px reach 5 px out. */
  .sd-chips a::after { content: ""; position: absolute; inset: -6px -5px; }
  .sd-sort a, .sd-sort button { position: relative; }
  .sd-sort a::after, .sd-sort button::after { content: ""; position: absolute; inset: -8px 0; }
}
@media (max-width: 640px) {
  .sd-hero .pg-title.is-xl { font-size: 34px; }
  .sd-hero .pg-lead { font-size: 16px; }
  .sd-search input { font-size: 16px; } /* 16 px: iOS does not zoom into the field */
  .sd-search kbd { display: none; }
  .sd-sort { flex: 1 1 100%; }
  .sd-sort a, .sd-sort button { flex: 1 1 auto; height: 30px; padding: 0 10px; }
  .sd-sort a::after, .sd-sort button::after { inset: -7px 0; } /* 30 px segment, 44 px to hit */
  .sd-head { margin-top: 14px; }
  .sd-own { padding: 40px 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .js .sd-list > .sd-item { animation: none; }
  .sd-sort button[aria-busy="true"] .ln-i { animation: none; opacity: .5; }
  .sd-chips a:active, .sd-sort a:active, .sd-sort button:active { transform: none; }
}

/* ── The places (/fahrschulen: the list of cities; /fahrschulen/<stadt>) ──
   Plain links, white on black: a city is a way in, not a filter. The city
   page (lib/school-city-render.js) is this page's frame around one place:
   its facts, its classes, its schools. Prefix `sc-` for what only it has. */
.sd-cities { margin-top: 56px; }
.sd-cities ul { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.sd-cities a { display: inline-flex; align-items: center; gap: 10px; min-height: 40px; padding: 0 14px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface); color: var(--ink); font-weight: var(--w-medium); transition: border-color var(--d-fast) ease, background var(--d-fast) ease; }
.sd-cities a[aria-current="page"] { border-color: var(--line-strong); background: var(--surface-raised); }
.sd-cities small { color: var(--ink-faint); font-family: var(--font-mono); font-size: var(--t-xs); }
.sc-facts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); margin: 0; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); }
.sc-facts > div { padding: 18px 20px; border-right: 1px solid var(--line); }
.sc-facts > div:last-child { border-right: 0; }
.sc-facts dt { color: var(--ink-muted); font-size: var(--t-sm); }
.sc-facts dd { margin: 6px 0 0; color: var(--ink); font-size: 20px; font-weight: var(--w-semi); letter-spacing: -0.02em; overflow-wrap: anywhere; }
.sc-facts dd small { display: block; margin-top: 2px; color: var(--ink-faint); font-size: var(--t-sm); font-weight: var(--w-normal); letter-spacing: 0; }
.sc-sec { margin-top: 56px; }
.sc-sec > p { max-width: 70ch; margin: -6px 0 18px; color: var(--ink-muted); line-height: 1.6; }
.sc-classes { width: 100%; border-collapse: collapse; border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; }
.sc-classes th, .sc-classes td { padding: 12px 16px; border-bottom: 1px solid var(--line-soft); text-align: left; }
.sc-classes tr:last-child th, .sc-classes tr:last-child td { border-bottom: 0; }
.sc-classes thead th { color: var(--ink-muted); font-size: var(--t-sm); font-weight: var(--w-medium); background: var(--surface); }
.sc-classes tbody th { width: 90px; font-family: var(--font-mono); font-weight: var(--w-medium); }
.sc-classes td:last-child { color: var(--ink-muted); text-align: right; white-space: nowrap; }
.sc-classes thead th:last-child { text-align: right; }
.sc-sortnote { margin-top: 10px; color: var(--ink-faint); font-size: var(--t-sm); }
.sc-sortnote a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  .sd-cities a:hover { border-color: var(--line-strong); background: var(--surface-raised); }
}
@media (max-width: 760px) {
  .sc-facts { grid-template-columns: 1fr 1fr; }
  .sc-facts > div:nth-child(2) { border-right: 0; }
  .sc-facts > div:nth-child(-n+2) { border-bottom: 1px solid var(--line); }
  .sc-classes th, .sc-classes td { padding: 10px 12px; }
  .sc-classes tbody th { width: 64px; }
}
