/* ============================================================
   Corsin — Portfolio
   Handgeschrieben, ohne Framework.
   Struktur: tokens · base · nav · hero · sections · project
             · timeline · contact · palette · responsive · print
   ============================================================ */

/* ---------- tokens: dark (default identity) ---------- */
:root{
  --bg: #0d1117;
  --bg-panel: #12181f;
  --bg-panel-2: #161d26;
  --bg-nav: rgba(13,17,23,0.85);
  --bg-overlay: rgba(6,9,13,0.72);
  --line: #232c37;
  --line-strong: #313c4a;
  --text: #e6edf3;
  --text-dim: #8b96a3;
  /* AA-geprüft: 4.76:1 auf --bg-panel, 5.05:1 auf --bg.
     Wird für echten Text genutzt (Metrik-Labels, Tags), nicht nur Deko. */
  --text-faint: #7a8593;
  --accent: #e6702c;
  --accent-hover: #b85a24;
  --accent-soft: rgba(230,112,44,0.12);
  --ok: #3ddc97;
  /* Status rot fürs Dashboard-Mockup (Speicherverbrauch). Validiert gegen
     dataviz-Skill: mode-invariant, >=3.5:1 auf bg/panel/panel-2 in beiden Themes.
     Bewusst rot statt orange, damit es nicht mit --accent verwechselt wird. */
  --crit: #d03b3b;
  --on-accent: #0d1117;

  --font-display: 'Space Grotesk', system-ui, sans-serif;
  --font-body: 'Inter', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, monospace;

  --nav-h: 56px;
  --radius: 6px;

  color-scheme: dark;
}

/* ---------- tokens: light ---------- */
/* Eigenes Palette-Design, keine Invertierung: wärmeres Off-White,
   abgedunkelter Akzent damit kleine Mono-Labels den Kontrast halten. */
:root[data-theme="light"]{
  --bg: #fbfaf8;
  --bg-panel: #ffffff;
  --bg-panel-2: #f4f2ee;
  --bg-nav: rgba(251,250,248,0.85);
  --bg-overlay: rgba(30,26,22,0.42);
  --line: #e4dfd6;
  --line-strong: #cec7ba;
  --text: #1a1d21;
  --text-dim: #59626d;
  --text-faint: #666f7a;
  --accent: #b8501a;
  --accent-hover: #97400f;
  --accent-soft: rgba(184,80,26,0.10);
  --ok: #0f7a54;
  --crit: #d03b3b;
  --on-accent: #ffffff;

  color-scheme: light;
}

/* System-Präferenz respektieren, solange nicht manuell umgeschaltet */
@media (prefers-color-scheme: light){
  :root:not([data-theme]){
    --bg: #fbfaf8;
    --bg-panel: #ffffff;
    --bg-panel-2: #f4f2ee;
    --bg-nav: rgba(251,250,248,0.85);
    --bg-overlay: rgba(30,26,22,0.42);
    --line: #e4dfd6;
    --line-strong: #cec7ba;
    --text: #1a1d21;
    --text-dim: #59626d;
    --text-faint: #666f7a;
    --accent: #b8501a;
    --accent-hover: #97400f;
    --accent-soft: rgba(184,80,26,0.10);
    --ok: #0f7a54;
    --crit: #d03b3b;
    --on-accent: #ffffff;

    color-scheme: light;
  }
}

/* ---------- base ---------- */
*{ margin:0; padding:0; box-sizing:border-box; }

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

body{
  background:var(--bg);
  color:var(--text);
  font-family:var(--font-body);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-wrap:break-word;
}

/* Theme-Wechsel weich, aber nur für Farben */
body,
nav,
.beyond,
.skill-group,
.project-card,
.hero-meta div,
.contact-grid a{
  transition:background-color .25s ease, border-color .25s ease, color .25s ease;
}

a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; background:none; border:none; cursor:pointer; }
ul{ list-style:none; }
svg{ display:block; }

::selection{ background:var(--accent); color:var(--on-accent); }

a:focus-visible,
button:focus-visible,
[tabindex]:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:3px;
  border-radius:2px;
}

.wrap{ max-width:960px; margin:0 auto; padding:0 28px; }

/* Nur für Screenreader */
.sr-only{
  position:absolute; width:1px; height:1px;
  padding:0; margin:-1px; overflow:hidden;
  clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* Skip-Link */
.skip-link{
  position:absolute; top:0; left:50%; transform:translate(-50%,-120%);
  z-index:200; background:var(--accent); color:var(--on-accent);
  font-family:var(--font-mono); font-size:13px; padding:10px 18px;
  border-radius:0 0 var(--radius) var(--radius);
  transition:transform .18s ease;
}
.skip-link:focus{ transform:translate(-50%,0); }

/* ---------- nav ---------- */
nav{
  position:sticky; top:0; z-index:50;
  background:var(--bg-nav);
  -webkit-backdrop-filter:blur(12px) saturate(140%);
  backdrop-filter:blur(12px) saturate(140%);
  border-bottom:1px solid var(--line);
}
nav .wrap{
  display:flex; align-items:center; justify-content:space-between;
  gap:20px; height:var(--nav-h);
}

.logo{
  font-family:var(--font-mono); font-size:14px;
  color:var(--text); white-space:nowrap; flex-shrink:0;
}
.logo span{ color:var(--accent); }

.nav-right{ display:flex; align-items:center; gap:22px; }

.navlinks{
  display:flex; gap:26px;
  font-family:var(--font-mono); font-size:13px;
}
.navlinks a{
  position:relative;
  color:var(--text-dim);
  padding:4px 0;
  transition:color .15s ease;
}
.navlinks a::after{
  content:""; position:absolute; left:0; right:0; bottom:-2px;
  height:1px; background:var(--accent);
  transform:scaleX(0); transform-origin:left;
  transition:transform .22s ease;
}
.navlinks a:hover{ color:var(--text); }
.navlinks a:hover::after{ transform:scaleX(.4); }

/* Scroll-Spy: aktive Section */
.navlinks a[aria-current="true"]{ color:var(--text); }
.navlinks a[aria-current="true"]::after{ transform:scaleX(1); }

/* Icon-Buttons rechts */
.nav-tools{ display:flex; align-items:center; gap:6px; }

.icon-btn{
  display:grid; place-items:center;
  width:34px; height:34px; border-radius:var(--radius);
  color:var(--text-dim);
  border:1px solid transparent;
  transition:color .15s ease, background-color .15s ease, border-color .15s ease;
}
.icon-btn:hover{
  color:var(--text);
  background:var(--bg-panel);
  border-color:var(--line);
}
.icon-btn svg{ width:17px; height:17px; }

/* ⌘K-Auslöser */
.kbd-trigger{
  display:flex; align-items:center; gap:9px;
  height:34px; padding:0 11px;
  font-family:var(--font-mono); font-size:12px;
  color:var(--text-faint);
  background:var(--bg-panel);
  border:1px solid var(--line); border-radius:var(--radius);
  transition:color .15s ease, border-color .15s ease;
}
.kbd-trigger:hover{ color:var(--text-dim); border-color:var(--line-strong); }
.kbd-trigger svg{ width:14px; height:14px; }
.kbd-trigger kbd{
  font-family:var(--font-mono); font-size:11px;
  color:var(--text-faint);
  background:var(--bg-panel-2);
  border:1px solid var(--line);
  border-radius:3px; padding:1px 5px;
}

/* Theme-Icons: je Modus nur eines sichtbar */
.icon-sun{ display:none; }
:root[data-theme="light"] .icon-sun{ display:block; }
:root[data-theme="light"] .icon-moon{ display:none; }
@media (prefers-color-scheme: light){
  :root:not([data-theme]) .icon-sun{ display:block; }
  :root:not([data-theme]) .icon-moon{ display:none; }
}

/* Hamburger */
.nav-toggle{ display:none; }
.nav-toggle .bar{
  display:block; width:17px; height:1.5px;
  background:currentColor; border-radius:2px;
  transition:transform .22s ease, opacity .18s ease;
}
.nav-toggle .bar + .bar{ margin-top:4px; }
.nav-toggle[aria-expanded="true"] .bar:nth-child(1){ transform:translateY(5.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .bar:nth-child(2){ opacity:0; }
.nav-toggle[aria-expanded="true"] .bar:nth-child(3){ transform:translateY(-5.5px) rotate(-45deg); }

/* Mobile-Panel */
.mobile-menu{
  display:none;
  position:fixed; inset:var(--nav-h) 0 auto 0; z-index:49;
  background:var(--bg);
  border-bottom:1px solid var(--line);
  padding:8px 0 18px;
}
.mobile-menu.open{ display:block; animation:slide-down .22s ease; }
@keyframes slide-down{ from{ opacity:0; transform:translateY(-8px); } }
.mobile-menu a{
  display:flex; align-items:baseline; gap:12px;
  font-family:var(--font-mono); font-size:16px;
  color:var(--text-dim);
  padding:14px 28px;
  border-bottom:1px solid var(--line);
}
.mobile-menu a:last-child{ border-bottom:none; }
.mobile-menu a::before{
  content:attr(data-num);
  font-size:11px; color:var(--accent);
}
.mobile-menu a:hover,
.mobile-menu a:focus-visible{ color:var(--text); background:var(--bg-panel); }

/* ---------- hero ---------- */
header.hero{
  padding:104px 0 76px;
  border-bottom:1px solid var(--line);
  position:relative; overflow:hidden;
  scroll-margin-top:var(--nav-h);
}

/* Sehr dezentes Raster im Hintergrund — Tiefe ohne Dekoration */
header.hero::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:
    linear-gradient(to right, var(--line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line) 1px, transparent 1px);
  background-size:64px 64px;
  opacity:.45;
  /* Weiche Maske, sonst liest sich das Raster als harte Kiste statt als Textur */
  -webkit-mask-image:radial-gradient(ellipse 115% 90% at 22% -15%, #000 0%, rgba(0,0,0,.5) 35%, transparent 72%);
  mask-image:radial-gradient(ellipse 115% 90% at 22% -15%, #000 0%, rgba(0,0,0,.5) 35%, transparent 72%);
}
header.hero .wrap{ position:relative; z-index:1; }

.status-line{
  font-family:var(--font-mono); font-size:12.5px; color:var(--ok);
  display:inline-flex; align-items:center; gap:9px; margin-bottom:28px;
  padding:6px 13px 6px 11px;
  border:1px solid var(--line); border-radius:100px;
  background:var(--bg-panel);
}
.dot{
  width:7px; height:7px; border-radius:50%;
  background:var(--ok); box-shadow:0 0 8px var(--ok);
  animation:pulse 2.4s ease-in-out infinite;
  flex-shrink:0;
}
@keyframes pulse{ 0%,100%{ opacity:1; } 50%{ opacity:.35; } }

/* "Applikationsentwickler" ist zu lang für kleine Viewports. Statt mitten im
   Wort zu brechen: Silbentrennung (lang="de" liefert die Trennregeln). */
.hero h1{
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(31px, 7vw, 68px); line-height:1.03;
  letter-spacing:-0.025em;
  -webkit-hyphens:auto;
  hyphens:auto;
  /* Sicherheitsnetz: hyphens:auto braucht ein Silbentrennungs-Wörterbuch, das
     nicht auf jeder Plattform/in jedem Browser zuverlässig vorhanden ist. Ohne
     Fallback wird das Wort dann unsichtbar von header.hero (overflow:hidden)
     abgeschnitten statt umzubrechen — sichtbar getestet bei 320px. */
  overflow-wrap:break-word;
}
.hero h1 .role{ color:var(--accent); }

.hero p.lead{
  margin-top:22px; max-width:580px;
  font-size:clamp(16px, 1.6vw, 17.5px); color:var(--text-dim);
}

.hero-meta{
  margin-top:38px;
  display:grid; grid-template-columns:repeat(3,1fr); gap:1px;
  background:var(--line); border:1px solid var(--line);
  max-width:620px;
}
.hero-meta div{ background:var(--bg-panel); padding:14px 16px; }
.hero-meta .k{
  font-family:var(--font-mono); font-size:10.5px;
  text-transform:uppercase; letter-spacing:.08em; color:var(--text-faint);
}
.hero-meta .v{
  font-family:var(--font-mono); font-size:13.5px;
  margin-top:5px; color:var(--text);
}

.cta-row{ margin-top:40px; display:flex; gap:14px; flex-wrap:wrap; }
.btn{
  font-family:var(--font-mono); font-size:13px;
  padding:12px 21px; border-radius:var(--radius);
  border:1px solid var(--accent);
  transition:background-color .16s ease, border-color .16s ease, color .16s ease, transform .16s ease;
}
.btn:active{ transform:translateY(1px); }
.btn.primary{ background:var(--accent); color:var(--on-accent); font-weight:500; }
.btn.primary:hover{ background:var(--accent-hover); border-color:var(--accent-hover); }
.btn.ghost{ border-color:var(--line); color:var(--text-dim); }
.btn.ghost:hover{ border-color:var(--text-dim); color:var(--text); }

/* ---------- section shell ---------- */
section{
  padding:88px 0;
  border-bottom:1px solid var(--line);
  scroll-margin-top:var(--nav-h);
}
footer{ scroll-margin-top:var(--nav-h); }

.eyebrow{
  font-family:var(--font-mono); font-size:12px; color:var(--accent);
  text-transform:uppercase; letter-spacing:.1em; margin-bottom:10px;
  display:flex; align-items:center; gap:10px;
}
.eyebrow::before{ content:"//"; color:var(--text-faint); }

h2.title{
  font-family:var(--font-display); font-weight:600;
  font-size:clamp(26px, 3.4vw, 32px);
  letter-spacing:-0.015em; margin-bottom:38px;
}

/* ---------- reveal ---------- */
.reveal{
  opacity:0; transform:translateY(16px);
  transition:opacity .6s ease, transform .6s ease;
}
.reveal.in{ opacity:1; transform:none; }

/* Gestaffelt: Kinder laufen versetzt ein */
.reveal-stagger > *{
  opacity:0; transform:translateY(14px);
  transition:opacity .55s ease, transform .55s ease;
}
.reveal-stagger.in > *{ opacity:1; transform:none; }
.reveal-stagger.in > *:nth-child(1){ transition-delay:.00s; }
.reveal-stagger.in > *:nth-child(2){ transition-delay:.09s; }
.reveal-stagger.in > *:nth-child(3){ transition-delay:.18s; }
.reveal-stagger.in > *:nth-child(4){ transition-delay:.27s; }
.reveal-stagger.in > *:nth-child(5){ transition-delay:.36s; }

/* ---------- about ---------- */
.about-grid{ display:grid; grid-template-columns:1.3fr 1fr; gap:48px; }
.about-grid p{ color:var(--text-dim); margin-bottom:16px; font-size:15.5px; }
.about-grid p:last-child{ margin-bottom:0; }
.about-grid p strong{ color:var(--text); font-weight:500; }

.beyond{
  background:var(--bg-panel); border:1px solid var(--line);
  border-radius:var(--radius); padding:22px;
  align-self:start;
}
.beyond h3{
  font-family:var(--font-mono); font-size:12px; color:var(--text-faint);
  text-transform:uppercase; letter-spacing:.08em; margin-bottom:14px;
}
.beyond ul{ display:flex; flex-direction:column; gap:10px; }
.beyond li{ font-size:14px; color:var(--text-dim); display:flex; gap:10px; }
.beyond li::before{ content:"›"; color:var(--accent); }

/* ---------- skills ---------- */
.skill-groups{
  display:grid; grid-template-columns:repeat(2,1fr); gap:1px;
  background:var(--line); border:1px solid var(--line);
}
.skill-group{ background:var(--bg-panel); padding:24px; }
.skill-group h4{
  font-family:var(--font-mono); font-size:11.5px; color:var(--accent);
  text-transform:uppercase; letter-spacing:.08em; margin-bottom:6px;
}
.skill-group .g-note{
  font-size:12.5px; color:var(--text-faint); margin-bottom:16px;
}
.skill-group ul{ display:flex; flex-wrap:wrap; gap:7px; }
.skill-group li{
  font-family:var(--font-mono); font-size:12.5px; color:var(--text-dim);
  border:1px solid var(--line); border-radius:100px; padding:4px 11px;
  background:var(--bg);
  transition:color .15s ease, border-color .15s ease;
}
.skill-group li:hover{ color:var(--text); border-color:var(--line-strong); }
.skill-group li.lead-skill{
  color:var(--accent); border-color:var(--accent);
  background:var(--accent-soft);
}

/* ---------- project ---------- */
.project-card{
  background:var(--bg-panel); border:1px solid var(--line);
  border-radius:var(--radius); overflow:hidden;
}
.project-head{ padding:28px 28px 0; }
.project-tag{
  font-family:var(--font-mono); font-size:11px; color:var(--text-faint);
  text-transform:uppercase; letter-spacing:.08em;
}
.project-head h3{
  font-family:var(--font-display); font-size:clamp(20px, 2.6vw, 25px);
  font-weight:600; margin-top:8px; letter-spacing:-0.01em;
  -webkit-hyphens:auto;
  hyphens:auto;
}
.project-head p{ color:var(--text-dim); font-size:15px; margin-top:12px; max-width:620px; }

.stack-row{ display:flex; flex-wrap:wrap; gap:8px; margin-top:18px; }
.chip{
  font-family:var(--font-mono); font-size:11.5px; color:var(--text-dim);
  border:1px solid var(--line); padding:5px 11px; border-radius:100px;
}

.metrics{
  margin-top:26px;
  display:grid; grid-template-columns:repeat(4,1fr);
  border-top:1px solid var(--line);
} 
.metrics div{ padding:18px 28px; border-right:1px solid var(--line); }
.metrics div:last-child{ border-right:none; }
.metrics .m-label{
  font-family:var(--font-mono); font-size:10.5px; color:var(--text-faint);
  text-transform:uppercase; letter-spacing:.06em;
}
.metrics .m-val{
  font-family:var(--font-mono); font-size:14px; color:var(--ok); margin-top:6px;
}

/* Unterblöcke innerhalb der Projektkarte */
.p-block{ border-top:1px solid var(--line); padding:26px 28px; }
.p-block > h4{
  font-family:var(--font-mono); font-size:11px; color:var(--text-faint);
  text-transform:uppercase; letter-spacing:.09em; margin-bottom:18px;
}

/* Live-Panel: nachgebaute Grafana-Ansicht (echtes Dashboard, siehe Screenshot) */
.panel-mock{
  background:var(--bg); border:1px solid var(--line);
  border-radius:var(--radius); overflow:hidden;
}

/* -- Kopfzeile: Breadcrumb + Filter-Chips -- */
.gf-topbar{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between;
  gap:10px 16px; padding:11px 15px; border-bottom:1px solid var(--line);
  font-family:var(--font-mono); font-size:11px;
}
.gf-crumb{ display:flex; align-items:center; gap:7px; color:var(--text-faint); min-width:0; }
.gf-crumb-current{
  flex:1; min-width:0;
  color:var(--text-dim); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.gf-sep{ color:var(--text-faint); }
.gf-filters{ display:flex; flex-wrap:wrap; gap:7px; }
.gf-chip{
  display:inline-flex; align-items:center; gap:5px;
  border:1px solid var(--line); border-radius:4px;
  padding:3px 9px; background:var(--bg-panel); color:var(--text-dim);
}
.gf-chip b{ color:var(--text-faint); font-weight:500; }

/* -- KPI-Reihen: rot = Speicherverbrauch, gruen = Einsparung -- */
.stat-grid{
  display:grid; grid-template-columns:repeat(3,1fr);
  border-bottom:1px solid var(--line);
}
.stat-grid--ok{ grid-template-columns:repeat(4,1fr); }
.stat-tile{
  padding:16px 18px; border-right:1px solid var(--line);
  display:flex; flex-direction:column; gap:8px; justify-content:center; min-height:78px;
}
.stat-tile:last-child{ border-right:none; }
.stat-label{
  font-family:var(--font-mono); font-size:10.5px; color:var(--text-faint);
  text-transform:uppercase; letter-spacing:.05em; line-height:1.3;
  /* lange zusammengesetzte Wörter (Einsparungspotenzial) müssen brechen können,
     sonst zwingen sie eine Grid-Spalte über ihre minmax(0,1fr)-Breite hinaus */
  overflow-wrap:break-word;
}
.stat-value{
  font-family:var(--font-mono); font-weight:500;
  font-size:clamp(20px, 2.6vw, 26px); line-height:1;
  /* Grosse Zahl traegt selbst den Status (rot=Verbrauch, gruen=Einsparung) —
     das ist die vom dataviz-Skill sanktionierte Statusfarben-Ausnahme:
     kein separates Mark daneben, die Zahl IST die Anzeige. Immer mit
     sichtbarem Text-Label (nie Farbe allein). */
}
.stat-value.tone-crit{ color:var(--crit); }
.stat-value.tone-ok{ color:var(--ok); }
.stat-unit{
  font-size:0.55em; font-weight:400; color:var(--text-faint);
  margin-left:3px; letter-spacing:.02em;
}

/* -- Meter (Kreisbogen): Anteil an einem Limit, gleiche Rampe fuer Fuellung/Track -- */
.stat-tile--meter{ align-items:center; }
.stat-label--center{ text-align:center; margin-top:-4px; }
.meter{ width:100%; max-width:120px; height:auto; overflow:visible; }
.meter .m-track{ fill:none; stroke:var(--line-strong); stroke-width:9; stroke-linecap:round; }
.meter .m-fill{ fill:none; stroke:var(--ok); stroke-width:9; stroke-linecap:round; }
/* Zahl liegt NEBEN dem Mark (dem Bogen) -> Textfarbe, nicht Datenfarbe */
.meter .m-value{ fill:var(--text); font-family:var(--font-mono); font-weight:600; font-size:17px; }

/* Halbkreis r=50 -> Bogenlänge L=π·50=157.08. dashoffset=L*(1-Anteil) blendet
   den Rest des Pfads aus. Für 58.3%: 157.08*(1-0.583)=65.50. Ruhezustand
   zeigt 0% (offset=L), Reveal animiert zum Zielwert. */
.meter .m-fill{ stroke-dasharray:157.08; stroke-dashoffset:157.08; }
.in .meter .m-fill{ animation:meter-draw 1.1s .3s ease-out forwards; }
@keyframes meter-draw{ to{ stroke-dashoffset:65.5; } }

/* -- Balken: "Einsparung nach Advisor-Typ" (Meter-Kontrakt als Liste) -- */
.bars-block{ padding:18px 20px 6px; border-bottom:1px solid var(--line); }
.bars-title{
  font-family:var(--font-mono); font-size:11px; color:var(--text-faint);
  text-transform:uppercase; letter-spacing:.06em; margin-bottom:14px;
}
.bar-row{ display:flex; align-items:center; gap:14px; margin-bottom:14px; }
.bar-row:last-child{ margin-bottom:0; }
.bar-cat{
  width:92px; flex-shrink:0; font-family:var(--font-mono); font-size:12.5px; color:var(--text-dim);
}
.bar-track{
  flex:1; height:10px; border-radius:5px; min-width:0;
  background:color-mix(in srgb, var(--ok) 16%, var(--bg-panel));
}
.bar-fill{
  height:100%; border-radius:5px; background:var(--ok);
  max-width:100%;
  /* Balken wachsen beim Reveal von 0 auf ihren Zielwert (inline width) */
  transform-origin:left; transform:scaleX(0);
}
.in .bar-fill{ animation:bar-grow .9s .2s ease-out forwards; }
@keyframes bar-grow{ to{ transform:scaleX(1); } }
/* Eigenes Flex-Kind statt absolut positioniert — sonst schneidet
   .project-card{overflow:hidden} den Wert am rechten Rand ab. */
.bar-val{
  width:44px; flex-shrink:0; text-align:right;
  font-family:var(--font-mono); font-size:12px; color:var(--text-dim);
  white-space:nowrap;
}

/* -- Tabelle: "Detailansicht pro Schema" -- */
.gf-table-wrap{ padding:16px 20px 18px; }
.gf-table-title{
  font-family:var(--font-mono); font-size:11px; color:var(--text-faint);
  text-transform:uppercase; letter-spacing:.06em; margin-bottom:12px;
}
.gf-table-scroll{ overflow-x:auto; }
.gf-table{
  width:100%; min-width:560px; border-collapse:collapse;
  font-family:var(--font-mono); font-size:12px;
}
.gf-table th{
  text-align:left; font-weight:500; color:var(--text-faint);
  text-transform:uppercase; letter-spacing:.04em; font-size:10.5px;
  padding:0 12px 8px 0; border-bottom:1px solid var(--line-strong);
  white-space:nowrap;
}
.gf-table td{
  padding:8px 12px 8px 0; border-bottom:1px solid var(--line);
  color:var(--text-dim); white-space:nowrap;
}
/* Zahlenspalten: Ausrichtung erfordert Tabellenziffern (anders als Stat-Kacheln) */
.gf-table td.num{ font-variant-numeric:tabular-nums; color:var(--text); }
.gf-table tr:last-child td{ border-bottom:none; }

/* Architektur-Diagramm (1:1 an die reale "Big Picture"-Vorlage angelehnt) */
.diagram-scroll{ overflow-x:auto; padding-bottom:4px; }
.diagram{ width:100%; min-width:760px; height:auto; }
/* rx als SVG-Attribut im Markup, nicht via CSS — Safari unterstützt es dort nicht */
.diagram .d-box{
  fill:var(--bg-panel-2); stroke:var(--line-strong); stroke-width:1;
}
/* Akzent = eigene Entwicklung (Python Script, Exporter); neutral = Standard-Infrastruktur */
.diagram .d-box-accent{ stroke:var(--accent); fill:var(--accent-soft); }
.diagram .d-title{
  fill:var(--text); font-family:var(--font-mono); font-size:11px; font-weight:500;
}
.diagram .d-sub{
  fill:var(--text-faint); font-family:var(--font-mono); font-size:9px;
}
.diagram .d-arrow{ stroke:var(--line-strong); stroke-width:1.2; fill:none; }
.diagram .d-flow-label{
  fill:var(--text-dim); font-family:var(--font-mono); font-size:9px; font-weight:500;
}
/* Konfigurationsdatei-Hinweise: eine Stufe leiser als der Fluss-Label */
.diagram .d-config-label{
  fill:var(--text-faint); font-family:var(--font-mono); font-size:8px; font-style:italic;
}
.diagram .d-head{ fill:var(--line-strong); }

/* Oracle-DB-Innenleben: Advisor-Box (rot umrandet, wie im Original) + Zylinder-Icon */
.diagram .d-crit-box{
  fill:color-mix(in srgb, var(--crit) 10%, transparent);
  stroke:var(--crit); stroke-width:1.2;
}
.diagram .d-crit-label{
  fill:var(--crit); font-family:var(--font-mono); font-size:8.5px; font-weight:500;
}
.diagram .d-cyl{ fill:none; stroke:var(--text-faint); stroke-width:1.2; }

/* Nutzer-Glyph (Viewer-Rolle) */
.diagram .d-user{ fill:none; stroke:var(--text-dim); stroke-width:1.4; stroke-linejoin:round; }
.diagram .d-user-fill{ fill:var(--bg-panel-2); stroke:var(--text-dim); stroke-width:1.4; }

/* Legende unter dem Diagramm */
.diagram-legend{
  display:flex; flex-wrap:wrap; gap:16px; margin-top:12px;
  font-family:var(--font-mono); font-size:10.5px; color:var(--text-faint);
}
.diagram-legend span{ display:inline-flex; align-items:center; gap:7px; }
.diagram-legend i{ width:9px; height:9px; border-radius:2px; flex-shrink:0; }
.diagram-legend .lg-own{ background:var(--accent-soft); border:1.2px solid var(--accent); }
.diagram-legend .lg-infra{ background:var(--bg-panel-2); border:1px solid var(--line-strong); }

/* Technische Entscheide */
.decisions{ display:grid; grid-template-columns:repeat(2,1fr); gap:1px; background:var(--line); }
.decision{ background:var(--bg-panel); padding:20px 22px; }
.decision h5{
  font-family:var(--font-display); font-size:14.5px; font-weight:600;
  margin-bottom:8px; display:flex; gap:9px; align-items:baseline;
}
.decision h5::before{
  content:"?"; color:var(--accent);
  font-family:var(--font-mono); font-size:13px;
}
.decision p{ font-size:13.5px; color:var(--text-dim); margin:0; }

/* ---------- timeline ---------- */
.timeline{ position:relative; padding-left:28px; }
.timeline::before{
  content:""; position:absolute; left:5px; top:6px; bottom:6px;
  width:1px; background:var(--line);
}
.t-item{ position:relative; padding-bottom:34px; }
.t-item:last-child{ padding-bottom:0; }
.t-item::before{
  content:""; position:absolute; left:-28px; top:5px;
  width:11px; height:11px; border-radius:50%;
  background:var(--bg); border:2px solid var(--accent);
}
.t-date{ font-family:var(--font-mono); font-size:11.5px; color:var(--accent); }
.t-role{ font-family:var(--font-display); font-size:17px; font-weight:600; margin-top:5px; }
.t-org{ font-size:14px; color:var(--text-dim); margin-top:3px; }
.t-desc{ font-size:14px; color:var(--text-dim); margin-top:8px; max-width:580px; }

/* ---------- contact ---------- */
footer{ padding:88px 0 60px; }
footer h2.title{ margin-bottom:16px; }
footer p.lead{ color:var(--text-dim); max-width:500px; margin-bottom:38px; font-size:16px; }

.contact-grid{
  display:grid; grid-template-columns:repeat(3,1fr); gap:1px;
  background:var(--line); border:1px solid var(--line);
}
.contact-grid a{
  background:var(--bg-panel); padding:20px; display:block;
  position:relative;
}
.contact-grid a:hover{ background:var(--bg-panel-2); }
.contact-grid a::after{
  content:"↗"; position:absolute; top:18px; right:18px;
  font-family:var(--font-mono); font-size:12px; color:var(--text-faint);
  opacity:0; transform:translate(-3px,3px);
  transition:opacity .18s ease, transform .18s ease;
}
.contact-grid a:hover::after{ opacity:1; transform:none; }
.contact-grid .k{
  font-family:var(--font-mono); font-size:10.5px; color:var(--text-faint);
  text-transform:uppercase; letter-spacing:.08em;
}
.contact-grid .v{
  font-family:var(--font-mono); font-size:13.5px; color:var(--text); margin-top:6px;
}

.foot-note{
  margin-top:50px; display:flex; flex-wrap:wrap; gap:8px 16px;
  align-items:center;
  font-family:var(--font-mono); font-size:11.5px; color:var(--text-faint);
}
.foot-note .hint kbd{
  font-family:var(--font-mono); font-size:10.5px; color:var(--text-dim);
  background:var(--bg-panel); border:1px solid var(--line);
  border-radius:3px; padding:1px 5px;
}

/* ---------- command palette ---------- */
.palette-backdrop{
  position:fixed; inset:0; z-index:100;
  background:var(--bg-overlay);
  -webkit-backdrop-filter:blur(3px);
  backdrop-filter:blur(3px);
  display:none;
  padding:14vh 20px 20px;
}
.palette-backdrop.open{ display:block; animation:backdrop-in .14s ease; }
@keyframes backdrop-in{ from{ opacity:0; } }

.palette{
  max-width:520px; margin:0 auto;
  background:var(--bg-panel); border:1px solid var(--line-strong);
  border-radius:10px; overflow:hidden;
  box-shadow:0 24px 60px -12px rgba(0,0,0,.6);
  animation:palette-in .18s ease;
}
@keyframes palette-in{ from{ opacity:0; transform:translateY(-10px) scale(.985); } }

.palette-input-row{
  display:flex; align-items:center; gap:11px;
  padding:14px 16px; border-bottom:1px solid var(--line);
}
.palette-input-row svg{ width:15px; height:15px; color:var(--text-faint); flex-shrink:0; }
#palette-input{
  flex:1; background:none; border:none; outline:none;
  font-family:var(--font-mono); font-size:14px; color:var(--text);
}
#palette-input::placeholder{ color:var(--text-faint); }
.palette-esc{
  font-family:var(--font-mono); font-size:10.5px; color:var(--text-faint);
  border:1px solid var(--line); border-radius:3px; padding:2px 6px;
  flex-shrink:0;
}

.palette-list{
  max-height:min(46vh, 340px); overflow-y:auto;
  padding:8px; scrollbar-width:thin;
}
.palette-group{
  font-family:var(--font-mono); font-size:10px; color:var(--text-faint);
  text-transform:uppercase; letter-spacing:.09em;
  padding:10px 10px 6px;
}
.palette-item{
  display:flex; align-items:center; gap:12px; width:100%;
  padding:9px 10px; border-radius:5px; text-align:left;
  font-size:14px; color:var(--text-dim);
  scroll-margin:8px;
}
.palette-item .p-ico{
  font-family:var(--font-mono); font-size:11px; color:var(--text-faint);
  width:16px; flex-shrink:0; text-align:center;
}
.palette-item .p-label{ flex:1; }
.palette-item .p-meta{
  font-family:var(--font-mono); font-size:10.5px; color:var(--text-faint);
}
.palette-item[aria-selected="true"]{
  background:var(--accent-soft); color:var(--text);
}
.palette-item[aria-selected="true"] .p-ico{ color:var(--accent); }

.palette-empty{
  padding:26px 12px; text-align:center;
  font-family:var(--font-mono); font-size:12.5px; color:var(--text-faint);
}

.palette-foot{
  display:flex; gap:16px; flex-wrap:wrap;
  padding:10px 16px; border-top:1px solid var(--line);
  font-family:var(--font-mono); font-size:10.5px; color:var(--text-faint);
}
.palette-foot span{ display:inline-flex; align-items:center; gap:6px; }
.palette-foot kbd{
  background:var(--bg-panel-2); border:1px solid var(--line);
  border-radius:3px; padding:1px 5px;
}

body.palette-open,
body.menu-open{ overflow:hidden; }

/* ---------- responsive ---------- */
@media (max-width:900px){
  .decisions{ grid-template-columns:1fr; }
}

@media (max-width:760px){
  .wrap{ padding:0 20px; }

  .navlinks{ display:none; }
  .kbd-trigger{ display:none; }
  .nav-toggle{ display:grid; place-items:center; }
  .nav-right{ gap:8px; }

  header.hero{ padding:72px 0 60px; }
  section{ padding:64px 0; }
  footer{ padding:64px 0 48px; }

  .hero-meta{ grid-template-columns:1fr; }
  .about-grid{ grid-template-columns:1fr; gap:32px; }
  .skill-groups{ grid-template-columns:1fr; }
  .metrics{ grid-template-columns:1fr 1fr; }
  .metrics div:nth-child(2){ border-right:none; }
  .metrics div:nth-child(1),
  .metrics div:nth-child(2){ border-bottom:1px solid var(--line); }
  .contact-grid{ grid-template-columns:1fr; }

  .project-head{ padding:22px 20px 0; }
  .p-block{ padding:22px 20px; }
  .metrics div{ padding:16px 20px; }

  .palette-backdrop{ padding:8vh 14px 14px; }

  /* Stat-Grids (Dashboard-Mock): panel-mock hat overflow:hidden, darum werden
     Kacheln bei 3/4 Spalten still weggeclippt statt zu scrollen — auf
     schmalen Screens auf 2 Spalten umbrechen. minmax(0,1fr) statt 1fr: pures
     1fr ist minmax(auto,1fr) — eine Spur mit einem langen, umbruchlosen Wort
     ("Einsparungspotenzial") weigert sich sonst zu schrumpfen und sprengt die
     Spaltenbreite. */
  .stat-grid,
  .stat-grid--ok{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .stat-tile{ border-right:none; border-bottom:1px solid var(--line); }
  /* Ungerade Position = linke Spalte -> rechte Trennlinie */
  .stat-grid > .stat-tile:nth-child(odd),
  .stat-grid--ok > .stat-tile:nth-child(odd){ border-right:1px solid var(--line); }
  /* Letzte 2 Kacheln = unterste Zeile jeder Spalte -> keine Trennlinie mehr nach unten
     (funktioniert auch bei ungerader Kachelzahl: die einzelne letzte Kachel hat
     ohnehin nichts mehr unter sich) */
  .stat-grid > .stat-tile:nth-last-child(-n+2),
  .stat-grid--ok > .stat-tile:nth-last-child(-n+2){ border-bottom:none; }
  /* Basis-Regel setzt align-items:center für die Desktop-Reihe; das muss hier
     auf stretch, sonst zentrieren sich Breadcrumb/Filter-Zeile in Spalten-Modus
     auf ihre eigene Inhaltsbreite statt auf die Panel-Breite zu schrumpfen.
     flex-wrap MUSS auf nowrap: column-direction + wrap ohne feste Höhe legt
     sonst mehrspaltig nebeneinander an statt schlicht untereinander. */
  .gf-topbar{ flex-direction:column; flex-wrap:nowrap; align-items:stretch; }
}

@media (max-width:420px){
  .metrics{ grid-template-columns:1fr; }
  .metrics div{ border-right:none; border-bottom:1px solid var(--line); }
  .metrics div:last-child{ border-bottom:none; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }

  *,
  *::before,
  *::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }

  /* Inhalte müssen ohne Animation trotzdem sichtbar sein */
  .reveal,
  .reveal-stagger > *{ opacity:1; transform:none; }
  .bar-fill{ transform:scaleX(1); }
  .meter .m-fill{ stroke-dashoffset:65.5; } /* siehe Berechnung bei .meter .m-fill oben */
  .dot{ animation:none; }
}

/* ---------- print ---------- */
@media print{
  :root{
    --bg:#fff; --bg-panel:#fff; --bg-panel-2:#fff;
    --line:#c8c8c8; --line-strong:#999;
    --text:#000; --text-dim:#333; --text-faint:#666;
    --accent:#000; --ok:#000; --crit:#000; --on-accent:#fff;
  }

  nav,
  .mobile-menu,
  .palette-backdrop,
  .cta-row,
  .skip-link,
  .panel-mock,
  .foot-note .hint{ display:none !important; }

  body{ background:#fff; color:#000; font-size:11pt; }
  header.hero{ padding:0 0 18pt; }
  header.hero::before{ display:none; }
  section, footer{ padding:18pt 0; break-inside:avoid; }
  .wrap{ max-width:none; padding:0; }

  .reveal,
  .reveal-stagger > *{ opacity:1 !important; transform:none !important; }

  .project-card,
  .beyond,
  .skill-group,
  .t-item,
  .decision{ break-inside:avoid; }

  /* URLs sichtbar machen, sonst sind Links auf Papier wertlos */
  .contact-grid a .v::after{ content:""; }
  a[href^="http"]::after{ content:" (" attr(href) ")"; font-size:9pt; color:#555; }
  .contact-grid a::after{ content:none; }
}
