/* ============================================================
   PINGBOOK · Layout
   ------------------------------------------------------------
   The app shell (floating sidebar island + content that makes
   room for it) and the page-level building blocks: page head,
   hero, section head, results grid.
   ============================================================ */

:root {
  --rail-gap: 0.75rem;   /* gap between the sidebar island and the viewport / content */
  --rail-collapsed: 5rem; /* collapsed rail width (rem-scaled below 1440) */
  --rail-w: var(--rail-collapsed);
  --rail-pad: 0.5rem;    /* .side L/R/bottom padding */
  /* Extra top inset inside the rail above the logo — shared with .main-top
     so crumbs / selection bar stay vertically centred on the logo. */
  --chrome-top-extra: 0.375rem;
  --chrome-top-inset: calc(var(--rail-pad) + var(--chrome-top-extra));
  --side-head-mt: 0.5rem;
  --side-head-h: 2.75rem;
  --side-toggle-h: 2.875rem;
  /* Viewport Y of the logo / main-chrome midline (from top of viewport). */
  --chrome-mid-y: calc(
    var(--rail-gap)
    + var(--chrome-top-inset)
    + var(--side-head-mt)
    + (var(--side-head-h) / 2)
  );
  --rail-btn: 3.125rem;  /* collapsed square nav / account buttons */
  --rail-btn-ml: calc((var(--rail-collapsed) - 2 * var(--rail-pad) - var(--rail-btn)) / 2);
  --rail-logo: 1.5rem;
  --rail-logo-pl: calc((var(--rail-collapsed) - 2 * var(--rail-pad) - var(--rail-logo)) / 2);
  --rail-icon: 1.5rem;   /* 02.09. (Mathias): 24px statt 22px, Hugeicons-Satz etwas größer */
  --rail-icon-pl: calc((var(--rail-btn) - var(--rail-icon)) / 2);
  --rail-av: 1.875rem;
  --rail-av-pl: calc((var(--rail-btn) - var(--rail-av)) / 2);
  --rail-dur: 0.36s;  /* collapse / expand duration */
  --rail-ease: cubic-bezier(0.7, 0, 0.3, 1); /* rail expand/collapse only */
  --mtop-h: 3.5rem;   /* mobile top-bar island height (≤720px, see sidebar.css) */
}
html.rail-expanded { --rail-w: 18.125rem; }

/* ≥1440: collapsed rail locks at 80px; expanded rail locks at 300px */
@media (min-width: 1440px) {
  :root {
    --rail-collapsed: 80px;
    --rail-pad: 8px;
    --rail-btn: 48px;
    --rail-logo: 23px;
    --rail-icon: 22px;
    --rail-av: 30px;
  }
  html.rail-expanded { --rail-w: 300px; }
}

/* ---- App shell ---- */
.app { min-height: 100vh; }

/* The sidebar is a fixed island (see components/sidebar.css); the content
   column simply makes room for it and slides when the rail expands.
   margin-right uses the dock motion (0.32s --ease) als Rückfall (etwa bei
   prefers-reduced-motion); beim normalen An-/Abdocken friert
   html.td-dock-flip (talent-detail.css) die Transition ein und die
   Kachel-FLIP in pb-talent-detail.js übernimmt die Bewegung. */
.app-main {
  margin-left: calc(var(--rail-w) + var(--rail-gap) * 2);
  min-height: 100vh;
  /* Flex-Column: Kinder verhalten sich wie Block-Elemente, aber der
     Legal-Fuß (.pb-legalfoot, margin-top:auto) rutscht auf kurzen
     Seiten ans Viewport-Ende statt mitten im Leerraum zu hängen. */
  display: flex;
  flex-direction: column;
  transition:
    margin-left var(--rail-dur) var(--rail-ease),
    margin-right 0.32s var(--ease);
}

/* ---- Top bar (crumbs / selection stack) — scrolls with the page ---- */
.main-top {
  position: static;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  /* Height = 2 × logo mid-Y so flex-centered crumbs / sel-bar share the
     same vertical centre as .side-head / .pb-logo (--chrome-mid-y). */
  min-height: calc(var(--chrome-mid-y) * 2);
  padding: 0.875rem clamp(1.5rem, 4vw, 3.5rem);
  background: transparent;
}

/* ---- Page width + paddings ----
   Content pages: max 1000px, centered. Same horizontal inset as
   `.main-top` (clamp 1.5–3.5rem). Home search grid is not a `.page`
   and stays full-bleed. */
.page {
  width: 100%;
  max-width: 1000px;
  margin-inline: auto;
  padding: 2.5rem clamp(1.5rem, 4vw, 3.5rem) 6rem;
  box-sizing: border-box;
}

.page-head { margin-bottom: var(--sp-8); }
.page-head h1 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--fs-display);
  line-height: var(--lh-tight);
  letter-spacing: var(--track-display);   /* Osmo-Standard: Display −3 % */
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.page-head .sub {
  margin-top: var(--sp-3);
  color: var(--text-soft);
  max-width: 60ch;
}
/* Osmo-Standard: H2-Skala läuft mit −2 % (H1 −3 %, Body −1 %) —
   galt vorher nur mobil, jetzt durchgängig. */
.page h2,
.sec-head h2 { letter-spacing: var(--track-heading); }

/* ---- Centered hero (home search) ----
   Matches the approved original: a tall, vertically-centered block
   so the greeting + composer sit mid-viewport and the grid follows
   below the fold. */
.hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 1.5rem 1.5rem 1.25rem;
  /* Viewport-based height, but capped at 40rem (with a sensible floor). */
  min-height: clamp(21.25rem, calc(100vh - 31.5rem), 40rem);
  box-sizing: border-box;
}
.hero h1 {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 2.5rem;
  line-height: var(--lh-tight);
  letter-spacing: var(--track-display);   /* Osmo-Standard: Display −3 % */
  margin: 0 0 1.625rem;
}

/* ---- Section head / results toolbar row ----
   The original has NO heading here — just the tools, right-aligned,
   sharing the grid's wide max-width + clamp padding so they line up. */
.sec-head {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  /* Same horizontal inset as .main-top → flush with the breadcrumb/checkout. */
  padding: 1.875rem clamp(1.5rem, 4vw, 3.5rem) 0.875rem;
}
.sec-tools { display: flex; align-items: center; gap: var(--sp-2); }

/* ---- Results grid ----
   Wide, full-bleed with up to 5 columns. Column count follows the GRID's
   own width (auto-fill + min tile), so docking talent-detail (which
   shrinks .app-main via margin-right) reflows tiles instead of squashing
   them. Cap: max(min-tile, (100% − 4×gap) / 5) keeps a 5-col ceiling. */
.grid {
  --grid-gap: clamp(1.875rem, 2.6vw, 4.5rem);
  --grid-min: 12.5rem; /* ~200px — below this, drop a column */
  /* 5 Spalten (12.08., Wunsch Mathias): auf dem 15"-MacBook rendert
     das Grid sonst vollflaechig mit vier zu breiten Kacheln. --grid-min
     (200px) bleibt die Untergrenze - auf schmalen Breiten (z. B. 1230px,
     wo 5 Spalten nur 183px ergaeben) laesst auto-fill von selbst eine
     Spalte fallen, die Schwerpunkte-Pillen brechen also nicht um. */
  --grid-max-cols: 5;
  /* Obergrenze pro Kachel (31.08., Wunsch Mathias): ohne sie wachsen die
     5 Spalten auf breiten Monitoren unbegrenzt mit und die Kacheln werden
     querformatig. Steigt ein Fuenftel der Breite ueber --grid-tile-max,
     nimmt auto-fill stattdessen eine weitere Spalte hinzu — die Kacheln
     bleiben also nahe der Obergrenze statt in die Breite zu gehen. */
  --grid-tile-max: 12.5rem;
  display: grid;
  gap: var(--grid-gap);
  /* Full width with the SAME horizontal inset as .main-top → the cards are
     flush LEFT with the breadcrumb and RIGHT with the selection/checkout bar. */
  padding: 0.5rem clamp(1.5rem, 4vw, 3.5rem) 7.5rem;
  grid-template-columns: repeat(
    auto-fill,
    minmax(
      /* min(100%,…) so a single column never overflows on tiny viewports */
      min(
        100%,
        max(
          var(--grid-min),
          min(
            var(--grid-tile-max),
            calc((100% - (var(--grid-max-cols) - 1) * var(--grid-gap)) / var(--grid-max-cols))
          )
        )
      ),
      1fr
    )
  );
}

/* Karten ausserhalb des Bildschirms gar nicht erst zeichnen.
   ------------------------------------------------------------
   Der Feed zeigt bis zu 68 Karten, jede mit einem Avatar, den das
   Backend als 800x800-Original ausliefert (Xano hält keine
   Thumbnails vor) und der mit 46px dargestellt wird. Zusammen sind
   das rund 167 MB dekodierte Bilddaten, die bei jedem Neuzeichnen
   heruntergerechnet werden müssen.

   Beim Scrollen schiebt der Compositor zwar nur eine fertige Ebene,
   aber jedes Neuzeichnen (Filterwechsel, Sortierung, Resize) muss
   alle sichtbaren Avatare erneut herunterrechnen.

   `content-visibility: auto` lässt den Browser alles überspringen,
   was nicht im Bild ist — kein Layout, kein Paint, kein Skalieren.
   `contain-intrinsic-size: auto 280px` hält dabei die Scrollhöhe
   stabil: 280px ist der Näherungswert für eine Karte, `auto` merkt
   sich die tatsächliche Höhe, sobald sie einmal gezeichnet wurde.

   Geprüft: keine Karte hat Inhalt, der über ihren Kasten hinausragt
   — das Paint-Containment schneidet also nichts ab. */
.grid > * {
  content-visibility: auto;
  contain-intrinsic-size: auto 280px;
}
/* AUSNAHME (31.08., gemeldet Mathias): der Hover-Lift schiebt die
   Karte 2px über die Oberkante hinaus — das Paint-Containment schnitt
   sie dort ab. Für die gerade überfahrene Kachel aufheben; sie ist
   ohnehin im Bild, das Skip-Verhalten der anderen bleibt. */
.grid > *:hover {
  content-visibility: visible;
}

/* Empty feed (no search hits) — spans the whole grid row. */
.feed-empty {
  grid-column: 1 / -1;
  margin: 0;
  padding: 3rem 0;
  text-align: center;
  font-size: var(--fs-body);
  color: var(--text-faint);
}

/* list view = ONE tile holding all the rows. The page inset moves from
   padding to margin (same clamp) so the tile's surface/shadow don't bleed
   to the viewport edge; bottom margin keeps the scroll clearance. */
.grid.as-list {
  grid-template-columns: 1fr;
  gap: 0;
  padding: 0;
  margin: 0.25rem clamp(1.5rem, 4vw, 3.5rem) 7.5rem;
  background: var(--surface);
  border-radius: var(--r-lg);
  overflow: hidden;
}

/* ---- Empty state ---- */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-3);
  padding: var(--sp-16) var(--sp-6);
  color: var(--text-soft);
}
.empty h2 { font-size: var(--fs-md); color: var(--text); }

/* ---- Tablet · 768–1199 ------------------------------------
   Die Rail bleibt als Navigation Rail stehen (Material 3: ab
   „medium" Fensterbreite Rail statt Bottom-Bar, iPad ebenso).
   Zwei Dinge weichen vom Desktop ab:

   1. Hochformat (<1024): das Ausklappen der Rail legt sich ÜBER
      den Inhalt, statt ihn zu schieben. Auf einem 820px-Tablet
      würde die ausgeklappte Rail (290px) sonst ein Drittel der
      Breite fressen. Das ist die iPad-Konvention — quer verdrängt
      die Sidebar den Inhalt, hoch überlagert sie ihn.
   2. Der Hero darf nicht die halbe Seite einnehmen: auf kurzen
      Querformat-Viewports (1024×768) sonst 340px von 768px.
   ------------------------------------------------------------ */
@media (min-width: 768px) and (max-width: 1023.98px) {
  .app-main { margin-left: calc(var(--rail-collapsed) + var(--rail-gap) * 2); }
  /* Ausgeklappt überlagert — Schatten trennt sie sichtbar vom Inhalt. */
  html.rail-expanded .side { box-shadow: var(--shadow-lg); }
}

@media (min-width: 768px) and (max-width: 1199.98px) {
  /* Kürzerer Hero: auf 768px Höhe (iPad quer) blieben sonst nur
     gut 400px für die erste Kartenreihe. */
  .hero { min-height: clamp(16rem, calc(100dvh - 26rem), 26rem); }

  /* Kopfzeile: Krümel + Auswahl-Leiste + Anmelden/Registrieren
     überschritten bei 768px die Breite um wenige Pixel und erzeugten
     einen horizontalen Scrollbalken. Schmalerer Innenabstand, und
     umbrechen statt überlaufen, falls die Auswahl-Leiste wächst. */
  .main-top {
    padding-inline: 1.25rem;
    flex-wrap: wrap;
    row-gap: var(--sp-2);
  }
  .sec-head { padding-inline: 1.25rem; }
  .grid { padding-inline: 1.25rem; }
  .grid.as-list { margin-inline: 1.25rem; }
  .page { padding-inline: 1.25rem; }
}

/* ---- Mobil · <768 ---- */
@media (max-width: 767.98px) {
  /* Overflowendes Desktop-Chrome (Auswahl-Leiste etc.) darf den Layout-
     Viewport nicht aufweiten — sonst rutschen fixe Inseln (.mtop) aus
     dem sichtbaren Bereich. clip statt hidden: kein Scroll-Container. */
  html, body { overflow-x: clip; }
  .app-main {
    margin-left: 0;
    /* Platz für die fixe .mtop-Insel (sidebar.css) — plus die
       Notch/Dynamic-Island-Höhe, sonst liegt die Insel darunter. */
    padding-top: calc(var(--mtop-h) + var(--rail-gap) + env(safe-area-inset-top, 0px));
    padding-bottom: calc(4.75rem + env(safe-area-inset-bottom, 0px));
  }
  /* Die 4.75rem sind der Platz der schwebenden Auswahl-Insel — die gibt es
     nur auf Seiten mit <pb-selection-bar> (Suche, Anfragen, Favoriten,
     Bewertungen). Ohne Insel hob die Reserve den Rechtsfuß ~76px über das
     Seitenende: er schwebte zwischen Inhalt und Unterkante (Profil,
     Anfrage-Detail/-Eingang, Einstellungen; Mathias 06.10.2026). Regel: der
     Fuß steht direkt unter dem Inhalt oder ganz unten, nie dazwischen. */
  .app-main:not(:has(pb-selection-bar)) {
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  /* Innenabstand und Gap = 1rem, also genau eine Basiszeile.
     Osmo hält bei 375px 15px Seitenrand und 15.38px Gitterabstand —
     mit der viewport-geführten Basis kommt 1rem dort auf 15.38px. */
  .page { padding: 1rem 1rem 4rem; }
  .main-top { padding-inline: 1rem; }
  .sec-head { padding: 1rem 1rem 0.75rem; }

  /* Mobil-Dichte (Mathias 04.10.2026: „zu viel Gescrolle für wenig
     Infos“): die Kopfzeile mit dem Krümel nimmt nur den Platz, den der
     Krümel braucht (vorher 112px für eine 26px-Pille); ein einzelner
     Krümel wiederholt nur den Seitentitel und entfällt. Die Leiste
     bleibt im DOM — auf manchen Seiten hängt die fixe Auswahl-Insel
     darin (display:none nähme sie mit). */
  .main-top { min-height: 0; padding-block: 1rem 0.875rem; }
  .main-top .bcrumbs { margin-bottom: 0; }
  /* Einzelner Krümel = der aktuelle ist das erste Kind (kein :has im :has). */
  .main-top:has(> .bcrumbs > .bcrumb.current:first-child) { padding-block: 0; }
  .main-top > .bcrumbs:has(> .bcrumb.current:first-child) { display: none; }
  .page-head { margin-bottom: 1.5rem; }

  /* Zwei Karten je Zeile (Mobil-Dichte 04.10.2026): die Kachel ist für
     ~180px Breite gebaut (Desktop-Raster); eine je Zeile machte sie nur
     höher, nicht informativer — 80 Profile waren 29 Bildschirme. */
  .grid {
    --grid-gap: 0.75rem;
    padding: 0.25rem 1rem 6rem;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .grid.as-list { margin-inline: 1rem; }

  /* Der Hero darf auf kurzen Handy-Viewports nicht die ganze erste
     Bildschirmhöhe belegen. dvh statt vh: die ein-/ausfahrende
     Browserleiste ändert vh nicht mit, dvh schon. */
  /* Mobil-Dichte 04.10.2026, zweite Runde (Mathias: „bei der Suche fehlt
     der Raum zum Atmen“): ohne Mindesthöhe, aber mit Luft oben und unten. */
  .hero {
    min-height: 0;
    padding: 2.75rem 1rem 2rem;
  }

  /* Überschriften wie auf Osmo: Grösse aus der Skala (--fs-display
     = 2.625em → 40.4px bei 375), Zeilenhöhe 1.0 und straffere
     Laufweite. Die vorherigen clamp()-Werte sind damit überflüssig —
     die Basis skaliert bereits mit dem Viewport. */
  .page-head h1 {
    font-size: 1.75em; /* ≈24px bei 390px (Mathias 04.10.2026: „viel kleiner“) */
    line-height: 1;
    letter-spacing: var(--track-display);
  }
  .sec-head h2,
  .page h2 { letter-spacing: var(--track-heading); }

  /* iOS Safari zoomt beim Fokussieren in jedes Feld unter 16px.
     Der Breakpoint deckt den Fall zusätzlich zur pointer-coarse-
     Regel in base.css ab (Handy-Breite ⇒ mobiles Gerät). */
  /* !important, weil das keine Gestaltungsentscheidung ist, sondern eine
     Geräteschwelle: unter 16px zoomt iOS beim Fokussieren in das Feld und
     der Nutzer sitzt danach in einer verschobenen Ansicht fest. Ohne das
     gewinnt jede Komponentenregel per Spezifität — bei `.am-card
     .pb-input`, `.wa-notes textarea` und `.ck-cluster .ck-clsel select`
     ist mir das dreimal hintereinander passiert.
     max() lässt grössere Werte unverändert durch. */
  input, select, textarea { font-size: max(16px, 1em) !important; }
}
