/* Broken Ladder Labs - Firmenseite.
   Die Wortmarke gibt alles vor: monolinear, geometrisch, schwarz/weiss.
   Der eine wiederkehrende Kniff sind die GEBROCHENEN Haarlinien - sie haben
   eine Luecke, genau wie das E und das A im Logo. Sonst nichts: keine Farbe
   ausser dem Produktpunkt, kein Verlauf, kein Schmuck. */

/* Selbst gehostet, nicht ueber das Google-CDN: sonst wandern IP-Adressen in
   die USA und die Seite braeuchte eine Einwilligung. Jost ist eine variable
   Schrift, eine Datei deckt 300-500 ab. */
@font-face {
  font-family: 'Jost';
  src: url('/assets/fonts/jost-latin.woff2') format('woff2');
  font-weight: 300 500;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: dark;
  --bg: #16161c;          /* exakt der Hintergrund der dunklen Logodatei */
  --fg: #f5f5f4;
  --dim: rgba(245, 245, 244, 0.58);
  --faint: rgba(245, 245, 244, 0.38);
  --rule: rgba(245, 245, 244, 0.15);
  --rule-strong: rgba(245, 245, 244, 0.34);
  --reef: #37c6ff;        /* Produktfarbe Deadman Reef, nur als Punkt */
  --pad: clamp(1.5rem, 5vw, 3rem);
}

*,
*::before,
*::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: 'Jost', 'Century Gothic', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-weight: 300;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  max-width: 62rem;
  margin: 0 auto;
  padding: var(--pad);
}

main {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(3rem, 10vh, 6.5rem);
  padding: clamp(2rem, 7vh, 4.5rem) 0;
}

/* ------------------------------------------------------------------ Hero */

.wordmark-wrap {
  position: relative;
  width: clamp(14rem, 40vw, 23rem);
}

.wordmark {
  display: block;
  width: 100%;
  height: auto;
}

/* Die Wortmarke bricht beim Laden. Das SVG liegt deckungsgleich ueber dem
   PNG: ein Flicken in Hintergrundfarbe verdeckt den gekippten E-Balken, ein
   gerader Balken liegt darueber, und das fehlende Stueck des A-Beins ist als
   Flaeche ergaenzt. Nach einer Sekunde kippt der Balken um 15 Grad (dann
   liegt er genau auf dem Original), das Stueck faellt, die Overlays
   verschwinden. Ein Klick auf die Wortmarke startet das von vorn. */
.wordmark-fix {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.fix-patch { fill: var(--bg); }
.fix-bar,
.fix-piece { fill: #fff; } /* das PNG ist reines Weiss, nicht --fg */

.fix-bar {
  transform-box: fill-box;
  transform-origin: center;
  animation: tilt 0.55s cubic-bezier(0.3, 0.8, 0.3, 1) 1s both;
}

.fix-e { animation: vanish 0.15s linear 1.55s both; }

.fix-piece { animation: fall 0.5s cubic-bezier(0.5, 0, 0.9, 0.6) 1.15s both; }

@keyframes tilt {
  to { transform: rotate(-15deg); }
}

@keyframes vanish {
  to { opacity: 0; }
}

@keyframes fall {
  60% { opacity: 1; }
  to { transform: translateY(40px); opacity: 0; }
}

/* Neustart per Klick: site.js setzt die Klasse kurz und nimmt sie wieder weg. */
.wordmark-wrap.replay .fix-bar,
.wordmark-wrap.replay .fix-e,
.wordmark-wrap.replay .fix-piece { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .wordmark-fix { display: none; }
}

h1 {
  margin: clamp(2rem, 6vh, 3.25rem) 0 0;
  max-width: 18ch;
  font-size: clamp(1.6rem, 5.4vw, 2.9rem);
  font-weight: 300;
  line-height: 1.18;
  letter-spacing: -0.01em;
}

.lede {
  margin: 1rem 0 0;
  max-width: 40ch;
  color: var(--dim);
  font-size: clamp(0.95rem, 2.2vw, 1.075rem);
}

/* -------------------------------------------------------------- Projekte */

.projects {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.75rem, 5vw, 3.5rem);
}

@media (max-width: 40rem) {
  .projects { grid-template-columns: 1fr; }
}

/* Die gebrochene Haarlinie. ::before ist die Linie, ::after ein Stueck in
   Hintergrundfarbe, das sie verdeckt: die Luecke. Wo die Luecke sitzt, sagt
   --gap. site.js schiebt sie dorthin, wo der Zeiger steht; ohne Zeiger
   (Touch) wandert sie langsam von selbst, siehe drift unten. */
.broken-rule {
  --gap: 21%;
  position: relative;
}

.broken-rule::before,
.broken-rule::after {
  content: "";
  position: absolute;
  top: 0;
  height: 1px;
}

.broken-rule::before {
  left: 0;
  right: 0;
  background: var(--rule);
  transition: background-color 0.35s ease;
}

.broken-rule::after {
  left: var(--gap);
  width: 9%;
  background: var(--bg);
  transition: left 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* Touch: keine Zeigerposition, also atmet die Luecke von selbst. Die drei
   Linien laufen phasenversetzt, damit sie nicht im Gleichschritt wandern. */
@media (pointer: coarse) {
  .broken-rule::after { animation: drift 26s ease-in-out infinite; }
  .card:nth-of-type(2)::after { animation-delay: -9s; }
  footer::after { animation-delay: -18s; }
}

@keyframes drift {
  0%, 100% { left: 6%; }
  50% { left: 85%; }
}

.card {
  padding-top: 1.6rem;
  min-width: 0; /* haelt ein langes Wort davon ab, die Spalte aufzublasen */
}

.card:hover::before,
.card:focus-within::before {
  background: var(--rule-strong);
}

/* Die Produkte bringen ihre Farbe mit: Deadman Reefs Linie wird cyan, die
   des namenlosen Produkts bleibt weiss, bis es eine Identitaet hat. */
.card--reef:hover::before,
.card--reef:focus-within::before {
  background: var(--reef);
}

.status {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 1.15rem;
  color: var(--faint);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  flex: none;
}

.dot--live { background: var(--reef); }
.dot--wip { border: 1px solid var(--faint); }

.card h2 {
  margin: 0 0 0.55rem;
  font-size: clamp(1.3rem, 3.2vw, 1.65rem);
  font-weight: 400;
  letter-spacing: 0.005em;
}

.card p {
  margin: 0;
  color: var(--dim);
}

.visit {
  display: inline-block;
  margin-top: 1rem;
  padding-bottom: 2px;
  border-bottom: 1px solid var(--rule-strong);
  color: var(--fg);
  font-size: 0.95rem;
  text-decoration: none;
  transition: border-color 0.2s ease;
}

.visit:hover { border-color: var(--fg); }

.arrow {
  display: inline-block;
  transition: transform 0.2s ease;
}

.visit:hover .arrow { transform: translate(2px, -2px); }

/* ---------------------------------------------------------------- Footer */

footer {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 1.15rem;
  padding-top: clamp(1.75rem, 5vh, 2.75rem);
  color: var(--faint);
  font-size: 0.8rem;
}

footer a {
  color: var(--dim);
  text-decoration: none;
  transition: color 0.2s ease;
}

footer a:hover { color: var(--fg); }
footer .mail { color: var(--fg); }
footer .sep { color: var(--rule-strong); }
footer .legal { margin-left: auto; }

@media (max-width: 40rem) {
  footer .legal {
    margin-left: 0;
    flex-basis: 100%;
  }
}

/* ----------------------------------------------------------- Rechtsseiten */

.prose { max-width: 44rem; }

.prose h1 {
  margin: 0 0 2.25rem;
  max-width: none;
  font-size: clamp(1.5rem, 4.5vw, 2.1rem);
}

.prose h2 {
  margin: 2.5rem 0 0.7rem;
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.03em;
}

.prose p {
  margin: 0 0 1rem;
  color: var(--dim);
}

.prose a { color: var(--fg); }
.prose a:hover { text-decoration: none; }

.prose .address {
  color: var(--fg);
  font-weight: 400;
}

/* Der Abstand nach unten kommt schon vom gap in main - hier nichts addieren. */
.masthead {
  display: inline-block;
  align-self: flex-start;
}

.masthead img {
  display: block;
  width: 9.5rem;
  height: auto;
  opacity: 0.8;
  transition: opacity 0.2s ease;
}

.masthead:hover img { opacity: 1; }

.prose .updated {
  color: var(--faint);
  font-size: 0.85rem;
}

/* ------------------------------------------------------------------ 404 */

/* Die fehlende Sprosse: eine Haarlinie mit grosser Luecke. Sie folgt dem
   Zeiger wie alle anderen, site.js liest die Breite der Luecke aus dem CSS. */
.missing .rung {
  --gap: 33%;
  height: 1px;
  margin-bottom: clamp(2rem, 6vh, 3rem);
}

.missing .rung::after { width: 34%; }

@media (pointer: coarse) {
  .missing .rung::after { animation-name: drift-wide; }
}

@keyframes drift-wide {
  0%, 100% { left: 4%; }
  50% { left: 62%; }
}

.missing h1 { margin-top: 0; }
.missing .lede a { color: var(--fg); }

/* ---------------------------------------------------------------- Druck */

.print-only { display: none; }

@media print {
  /* Alle Seiten: dunkel auf hell, sonst steht helle Schrift auf weissem
     Papier, weil Browser Hintergruende nicht drucken. */
  body { background: #fff; color: #16161c; }
  .skip { display: none; }
  .wordmark, .masthead img { filter: invert(1); opacity: 1; }
  .lede, .prose p, .prose .updated, footer, footer a, footer .mail { color: #16161c; }
  .broken-rule::before { background: #16161c; opacity: 0.25; }
  .broken-rule::after { background: #fff; }
  .rise { animation: none; }

  /* Die Startseite druckt sich als Visitenkarte, 85 x 55 mm: Wortmarke, der
     eine Satz, die Adresse. Die Seite nennt sich Visitenkarte, also
     verhaelt sie sich auch so. */
  @page { size: 85mm 55mm; margin: 0; }
  body.home .page { max-width: none; min-height: 0; padding: 0; }
  body.home main { display: block; padding: 0; }
  body.home .projects, body.home footer, body.home .lede { display: none; }
  body.home .hero {
    box-sizing: border-box;
    width: 85mm;
    height: 55mm;
    padding: 7mm 8mm;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
  }
  body.home .wordmark-wrap { width: 30mm; }
  .wordmark-fix { display: none; }
  body.home h1 {
    margin: 0;
    max-width: none;
    font-size: 10.5pt;
    line-height: 1.3;
    letter-spacing: 0;
  }
  body.home .print-only {
    display: block;
    margin: 0;
    font-size: 7.5pt;
    letter-spacing: 0.02em;
    color: #16161c;
  }
}

/* ------------------------------------------------------- Zugaenglichkeit */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  padding: 0.7rem 1.1rem;
  background: var(--fg);
  color: var(--bg);
  text-decoration: none;
}

.skip:focus {
  left: 0.5rem;
  top: 0.5rem;
}

a:focus-visible,
.masthead:focus-visible {
  outline: 1px solid var(--fg);
  outline-offset: 4px;
}

/* ---------------------------------------------------------------- Auftritt */

@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

.rise {
  animation: rise 0.75s cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}

.rise-2 { animation-delay: 0.09s; }
.rise-3 { animation-delay: 0.17s; }
.rise-4 { animation-delay: 0.26s; }

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
