/* saschahenning.de — private personal site. "Playful" final.
   Pure-CSS + tiny self-hosted JS (CSP script-src 'self').
   Fully usable without JS; all motion off under prefers-reduced-motion.
   Theme: light default + system-dark + user-overridable via [data-theme]. */

/* Cross-document View Transitions — SPA-like nav, zero JS, graceful.
   Kept here (not inline) so the CSP needs no style-src 'unsafe-inline'. */
@view-transition{navigation:auto}

/* ---- Theme tokens ---- */
:root{
  color-scheme:light;
  --bg-base:#fff7ed;
  --bg-rose:#ffe3ef;
  --bg-blue:#dbeafe;
  --fg:#1b1b1f;
  --muted:#4a4a52;
  --dim:#6a6a72;
  --hairline:rgba(27,27,31,.15);
  --ink:#1b1b1f;        /* heavy borders & hard shadows */
  --pill-bg:#fff;
  --card-bg:#fff;
  --about-bg:#1b1b1f;
  --about-fg:#fdfaf3;
  --about-dim:#dcd8cc;
  --accent-pink:#ff5d8f;
  --accent-blue:#3b82f6;
  --accent-green:#16c79a;
  --accent-yellow:#ffd23f;
  --grain-opacity:.045;
  --grain-blend:overlay;
  --cursor-blend:multiply;
}
:root[data-theme="dark"]{
  color-scheme:dark;
  --bg-base:#0d0e12;
  --bg-rose:rgba(255,93,143,.10);
  --bg-blue:rgba(59,130,246,.10);
  --fg:#f0eee8;
  --muted:#b6b3aa;
  --dim:#8a8a82;
  --hairline:rgba(240,238,232,.15);
  --ink:#f0eee8;
  --pill-bg:#16161a;
  --card-bg:#16161a;
  --about-bg:#22232a;
  --about-fg:#fdfaf3;
  --about-dim:#c8c4b8;
  --grain-opacity:.07;
  --grain-blend:soft-light;
  --cursor-blend:difference;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --bg-base:#0d0e12;
    --bg-rose:rgba(255,93,143,.10);
    --bg-blue:rgba(59,130,246,.10);
    --fg:#f0eee8;
    --muted:#b6b3aa;
    --dim:#8a8a82;
    --hairline:rgba(240,238,232,.15);
    --ink:#f0eee8;
    --pill-bg:#16161a;
    --card-bg:#16161a;
    --about-bg:#22232a;
    --about-fg:#fdfaf3;
    --about-dim:#c8c4b8;
    --grain-opacity:.07;
    --grain-blend:soft-light;
    --cursor-blend:difference;
  }
}

/* ---- Base ---- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
img{max-width:100%}
a{color:inherit}

body{
  margin:0;min-height:100vh;color:var(--fg);
  font-family:ui-rounded,"SF Pro Rounded","Segoe UI",system-ui,-apple-system,sans-serif;
  background:
    radial-gradient(60% 50% at 88% 0%,var(--bg-rose) 0%,transparent 60%),
    radial-gradient(55% 45% at 0% 100%,var(--bg-blue) 0%,transparent 55%),
    var(--bg-base);
}

.wrap{max-width:1080px;margin:0 auto;padding:clamp(1.4rem,4vw,3rem)}

/* ---- Top bar ---- */
.bar{display:flex;align-items:center;justify-content:space-between;
  gap:1rem;flex-wrap:wrap;margin-bottom:1.4rem}
.wordmark{font-weight:800;letter-spacing:-.02em;font-size:.95rem;opacity:.7}
.bar-nav{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center}
.bar-nav a,.back,.theme-toggle{display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;padding:.4rem .9rem;border-radius:999px;border:2px solid var(--ink);
  font-size:.85rem;font-weight:700;text-decoration:none;background:var(--pill-bg);
  color:var(--fg);cursor:pointer;font-family:inherit;
  transition:transform .15s,background .15s,color .15s,border-color .15s}
.bar-nav a:hover,.back:hover,.theme-toggle:hover{background:var(--ink);color:var(--bg-base)}
.back{background:var(--ink);color:var(--bg-base)}

/* Theme toggle: show the icon of the mode you'll switch TO. */
.theme-toggle{padding:.4rem .7rem;min-width:44px;font-size:1rem;line-height:1;
  font-variant-emoji:text}
.theme-toggle .t-sun{display:none}
.theme-toggle .t-moon{display:inline}
:root[data-theme="dark"] .theme-toggle .t-sun{display:inline}
:root[data-theme="dark"] .theme-toggle .t-moon{display:none}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .theme-toggle .t-sun{display:inline}
  :root:not([data-theme="light"]) .theme-toggle .t-moon{display:none}
}

/* ---- Hero ---- */
.top{display:grid;grid-template-columns:1.2fr .8fr;gap:2.5rem;
  align-items:center;margin:1.6rem 0 2.6rem}
h1{font-size:clamp(2.3rem,7.5vw,4.4rem);margin:0;line-height:1.06;
  letter-spacing:-.03em;font-weight:800}
.wave{display:inline-block;transform-origin:70% 70%;
  animation:wave 2.4s ease-in-out infinite}
@keyframes wave{0%,60%,100%{transform:rotate(0)}10%,30%{transform:rotate(16deg)}20%{transform:rotate(-8deg)}}
.sub{font-size:clamp(1.05rem,2.4vw,1.35rem);color:var(--muted);
  margin:1.1rem 0 1.4rem;max-width:42ch;line-height:1.55}
.stats{display:flex;flex-wrap:wrap;gap:.6rem}
.stats b{display:inline-flex;align-items:center;gap:.45rem;font-size:.85rem;
  font-weight:700;background:var(--pill-bg);color:var(--fg);
  border:2px solid var(--ink);border-radius:999px;padding:.4rem .85rem}
.pic{position:relative;justify-self:center}
.pic img{width:min(320px,72vw);height:auto;display:block;
  border-radius:46% 54% 58% 42%/52% 46% 54% 48%;
  border:5px solid var(--ink);animation:wob 7s ease-in-out infinite}
@keyframes wob{0%,100%{border-radius:46% 54% 58% 42%/52% 46% 54% 48%;transform:rotate(-1.5deg)}
  50%{border-radius:58% 42% 46% 54%/46% 56% 44% 54%;transform:rotate(2deg)}}
.pic .blob{position:absolute;width:46px;height:46px;border-radius:50%;
  background:var(--accent-yellow);top:-14px;left:-10px;z-index:-1}
.pic .blob.b2{background:var(--accent-green);width:30px;height:30px;
  bottom:8px;right:-14px;top:auto;left:auto}

/* ---- Sections ---- */
.block{margin:2.4rem 0}
.block h2{display:flex;align-items:center;gap:.6rem;margin:0 0 .7rem;
  font-size:1.25rem;font-weight:800}
.dot{width:15px;height:15px;border-radius:50%;display:inline-block;flex:none}
.c1{background:var(--accent-pink)}.c2{background:var(--accent-blue)}.c3{background:var(--accent-green)}
.lead{margin:0 0 1.3rem;color:var(--muted);line-height:1.65;max-width:64ch}
.note{margin:1.2rem 0 0;font-size:.92rem;color:var(--dim);line-height:1.6;
  max-width:64ch}
.cards{display:grid;gap:1.1rem;
  grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.sublabel{margin:2rem 0 .9rem;font-weight:800;font-size:1rem;color:var(--fg)}
.card{display:flex;flex-direction:column;gap:.45rem;padding:1.4rem;
  border-radius:20px;border:3px solid var(--ink);background:var(--card-bg);
  box-shadow:6px 6px 0 var(--ink);text-decoration:none;color:var(--fg);
  transition:transform .15s ease,box-shadow .15s ease}
a.card:hover,a.card:focus-visible{transform:translate(-3px,-3px);
  box-shadow:9px 9px 0 var(--ink)}
/* A project with no public entry point: dashed edge + flatter shadow so it
   reads as "exists, but not a link" instead of a dead click target. */
.card-static{border-style:dashed;box-shadow:4px 4px 0 var(--ink);cursor:default}
.card strong{font-size:1.1rem;display:flex;align-items:center;gap:.4rem}
.card span{color:var(--muted);font-size:.95rem;line-height:1.5;font-weight:600}
.arr{color:var(--accent-pink);font-weight:800}
.tags{margin:0;font-weight:700;color:var(--muted);font-size:.95rem;line-height:1.7}
.links{display:flex;flex-wrap:wrap;gap:.7rem}
.links a{display:inline-flex;align-items:center;gap:.4rem;min-height:44px;
  padding:.5rem 1.1rem;border-radius:999px;border:3px solid var(--ink);
  background:var(--pill-bg);color:var(--fg);font-weight:700;text-decoration:none;
  transition:transform .15s,background .15s,color .15s}
.links a:hover{background:var(--ink);color:var(--bg-base)}
.links a:hover .arr{color:inherit}

/* ---- About (always contrasting) ---- */
.about{margin:2.6rem 0 0;padding:2rem;border-radius:22px;
  border:3px solid var(--ink);background:var(--about-bg);color:var(--about-fg)}
.about h2{margin:0 0 .7rem;font-size:1.2rem}
.about p{margin:0;line-height:1.7;color:var(--about-dim);max-width:66ch}

/* ---- Legal / imprint ---- */
.legal{max-width:60ch;line-height:1.7}
.legal h1{font-size:clamp(1.8rem,5vw,2.6rem);margin:.5rem 0 1.4rem;
  letter-spacing:-.02em}
.legal p{margin:0 0 1rem}
.legal a{font-weight:700;text-decoration:underline}

/* ---- Footer ---- */
.site-footer{display:flex;flex-wrap:wrap;justify-content:space-between;
  gap:.4rem 1rem;max-width:1080px;margin:1.5rem auto 2.5rem;
  padding:1.2rem clamp(1.4rem,4vw,3rem) 0;font-size:.82rem;color:var(--dim);
  border-top:1px solid var(--hairline)}
.dim{color:var(--dim)}
.site-footer a{color:inherit;text-decoration:underline;
  display:inline-block;min-height:40px;line-height:40px}
.site-footer .rights{flex-basis:100%;font-size:.78rem;margin-top:.2rem;max-width:80ch}

/* ---- FX layer ---- */
.fx-grain{position:fixed;inset:0;z-index:9000;pointer-events:none;
  opacity:var(--grain-opacity);mix-blend-mode:var(--grain-blend);
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
#fx-cursor{position:fixed;top:0;left:0;width:26px;height:26px;
  margin:-13px 0 0 -13px;border-radius:50%;z-index:9001;pointer-events:none;
  border:2px solid var(--accent-pink);mix-blend-mode:var(--cursor-blend)}
@media (hover:none),(pointer:coarse){#fx-cursor{display:none}}

a:focus-visible,.card:focus-visible,button:focus-visible{outline:3px solid var(--accent-blue);
  outline-offset:3px;border-radius:6px}

/* ---- Motion ---- */
@media (prefers-reduced-motion:no-preference){
  .top,.block,.about{opacity:0;animation:rise .55s ease both}
  .block:nth-of-type(1){animation-delay:.05s}
  .block:nth-of-type(2){animation-delay:.12s}
  .block:nth-of-type(3){animation-delay:.19s}
  .about{animation-delay:.24s}
  @keyframes rise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{animation:none!important;transition:none!important}
  .fx-grain{display:none}
}

/* ---- Responsive ---- */
@media (max-width:760px){
  .top{grid-template-columns:1fr;gap:1.6rem}
  .pic{order:-1}
  .about{padding:1.5rem}
}

/* ---- App pages (/apps/…) ---- */
.app-hero{margin:1.2rem 0 2.4rem}
.app-kicker{margin:0 0 .5rem;font-weight:800;font-size:.8rem;
  letter-spacing:.09em;text-transform:uppercase;color:var(--dim)}
.app-hero h1{font-size:clamp(2.2rem,6.5vw,3.8rem);margin:0;line-height:1.06;
  letter-spacing:-.03em;font-weight:800}
.app-actions{margin:1.5rem 0 0;display:flex;flex-wrap:wrap;gap:1rem;align-items:center}
/* Apple badge: fixed artwork, only scaled — height matches the CTA pill. */
.store-badge{display:inline-flex;align-items:center}
.store-badge img{display:block;height:54px;width:auto}
.app-choice{margin:.9rem 0 0;font-size:.9rem;font-weight:600;color:var(--dim);max-width:64ch}
.app-cta{display:inline-flex;align-items:center;gap:.5rem;min-height:48px;
  padding:.7rem 1.4rem;border-radius:999px;border:3px solid var(--ink);
  background:var(--accent-yellow);color:#1b1b1f;font-weight:800;
  font-size:1.05rem;text-decoration:none;box-shadow:5px 5px 0 var(--ink);
  transition:transform .15s ease,box-shadow .15s ease}
.app-cta:hover,.app-cta:focus-visible{transform:translate(-2px,-2px);
  box-shadow:7px 7px 0 var(--ink)}
.app-cta .arr{color:inherit}
/* Text blocks (intro prose, install section). The intro additionally
   spreads over two columns on wide screens so it uses the page width. */
.app-body p,.app-body li{color:var(--muted);line-height:1.65;max-width:64ch}
.app-body p{margin:0 0 1rem}
.app-body ul{margin:0 0 1rem;padding-left:1.15rem}
.app-body li{margin:.5rem 0}
.app-body li::marker{color:var(--accent-pink)}
.app-body strong{color:var(--fg)}
.app-prose{display:grid;gap:0 3rem}
@media (min-width:900px){
  .app-prose{grid-template-columns:1fr 1fr}
  .app-prose p{max-width:none}
}
/* Screenshots: sized so a full set fills the row, without upscaling the
   390px-wide captures. */
.shots{display:flex;flex-wrap:wrap;gap:1.5rem;align-items:flex-start}
.shot{flex:1 1 205px;max-width:300px;margin:0}
.shot img{width:100%;height:auto;display:block;border:3px solid var(--ink);
  border-radius:24px;box-shadow:6px 6px 0 var(--ink);background:#fff}
.shot figcaption{margin:.7rem .2rem 0;font-size:.88rem;font-weight:600;
  color:var(--dim);line-height:1.5}
.about .app-actions{margin:1.2rem 0 0}
/* Apple App Store badge: used as provided, no recolouring. Padding gives it
   the clear space Apple's badge guidelines require around the artwork. */
.app-store-badge{display:inline-block;padding:8px}
.app-store-badge img{height:40px;width:auto;display:block}
@media (prefers-reduced-motion:no-preference){
  .app-hero{opacity:0;animation:rise .55s ease both}
}
