/* Komar Labs — komarlabs.dev
   Parent-brand page. Shares the house palette with the product sites
   (#07070d field, #c946ff accent, bracket motif) but stays quieter than
   both: this page introduces the studio, the product sites do the selling.
   No JavaScript anywhere on this site, which is what lets the CSP in
   infra/template.yaml stay at default-src 'none'. */

:root {
  --bg: #07070d;
  --bg-raised: #0c0b13;
  --line: rgba(201, 70, 255, 0.16);
  --accent: #c946ff;
  --accent-dim: rgba(201, 70, 255, 0.55);
  --text: #e9e6f2;
  --muted: #8b8799;   /* 5.8:1 on --bg */
  /* 4.8:1 on --bg and 4.6:1 on --bg-raised, so it clears WCAG AA for normal
     text on both. It carries the footer legal copy and the mono labels, which
     are small; a dimmer grey looked better in isolation and was unreadable. */
  --faint: #7d7891;

  --font: "Outfit", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Ignition clock. Mirrors KomarLabsIdent.gd: line in at 0.45s, glint sweep
     0.55–1.35s, collapse 1.55s, thump 1.95s, lockup reveal 2.03s. */
  --ign: 2.6s;
}

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

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

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-weight: 300;
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Small mono label used above each section. */
.eyebrow {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 2.4rem;
}
.eyebrow::before { content: "[ "; color: var(--accent-dim); }
.eyebrow::after  { content: " ]"; color: var(--accent-dim); }


/* ══════════════════════════ HERO ══════════════════════════ */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 6rem 1.5rem 5rem;
  overflow: hidden;
}

/* Magenta wash behind everything, brightest at the lockup. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 70% 55% at 50% 45%, rgba(201, 70, 255, 0.13), transparent 70%),
    radial-gradient(ellipse 120% 80% at 50% 120%, rgba(88, 20, 140, 0.10), transparent 70%);
  pointer-events: none;
}

.hero-inner { position: relative; z-index: 2; max-width: 720px; width: 100%; }

.lockup { line-height: 1; margin-bottom: 1.6rem; }
.lockup img {
  display: block;
  margin: 0 auto;
  width: clamp(260px, 52vw, 540px);
  height: auto;
  filter:
    drop-shadow(0 0 24px rgba(201, 70, 255, 0.45))
    drop-shadow(0 0 60px rgba(201, 70, 255, 0.20));
}

.tagline {
  font-family: var(--mono);
  font-size: clamp(0.68rem, 1.7vw, 0.82rem);
  font-weight: 400;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 2rem;
  /* letter-spacing adds a trailing gap after the LAST glyph too, so a centred
     line sits half a space left of true centre. Nudge back by half. */
  text-indent: 0.18em;
}

.lede {
  max-width: 46ch;
  margin: 0 auto;
  font-size: clamp(1rem, 2vw, 1.12rem);
  color: var(--muted);
}

/* Scroll cue: a bracket that breathes. */
.cue {
  position: absolute;
  bottom: 2.2rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--faint);
  padding: 0.6rem 1rem;
  /* Two animations: a one-shot fade that lands after the lockup has settled,
     then the endless breath. Without the fade the cue would sit at full
     opacity through the whole ignition and pull the eye off the reveal. */
  animation:
    cue-in 0.7s ease-out backwards,
    breathe 3.4s ease-in-out 0s infinite;
  animation-delay:
    calc(var(--ign) * 0.78 + 0.35s),
    calc(var(--ign) * 0.78 + 1.05s);
}
.cue:hover { color: var(--accent); text-decoration: none; }
.cue span::before { content: "↓  "; }

@keyframes cue-in {
  from { opacity: 0; transform: translate(-50%, 8px); }
  to   { opacity: 0.9; transform: translate(-50%, 0); }
}

@keyframes breathe {
  0%, 100% { opacity: 0.45; }
  50%      { opacity: 0.9; }
}


/* ─────────────── The ignition ───────────────
   Three layers sitting on the hero's midline: the scanline, the glint that
   travels it, and the shockwave ring the thump throws off. All three are
   decorative and marked aria-hidden. */

.ignition {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 0;
  z-index: 1;
  pointer-events: none;
}

.scanline {
  position: absolute;
  top: 0;
  left: 8%;
  right: 8%;
  height: 2px;
  transform-origin: 50% 50%;
  background: linear-gradient(
    to right,
    transparent,
    rgba(201, 70, 255, 0.55) 12%,
    rgba(230, 150, 255, 0.85) 50%,
    rgba(201, 70, 255, 0.55) 88%,
    transparent);
  box-shadow: 0 0 12px rgba(201, 70, 255, 0.5), 0 0 34px rgba(201, 70, 255, 0.25);
  opacity: 0;
  animation: scanline var(--ign) linear forwards;
}

/* fade in → hold → collapse to a point → gone */
@keyframes scanline {
  0%     { opacity: 0;    transform: scaleX(1); }
  17%    { opacity: 1;    transform: scaleX(1); }
  59%    { opacity: 1;    transform: scaleX(1); }
  74%    { opacity: 1;    transform: scaleX(0.02); }
  75%    { opacity: 0;    transform: scaleX(0); }
  100%   { opacity: 0;    transform: scaleX(0); }
}

.glint {
  position: absolute;
  top: 50%;
  left: 8%;
  width: 190px;
  height: 190px;
  margin: -95px 0 0 -95px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(255, 250, 255, 0.95) 0%,
    rgba(228, 130, 255, 0.55) 18%,
    rgba(201, 70, 255, 0.22) 38%,
    transparent 70%);
  opacity: 0;
  animation: glint var(--ign) cubic-bezier(0.45, 0, 0.55, 1) forwards;
}

/* Travels the line left → right, then dies before the collapse. */
@keyframes glint {
  0%, 20%  { opacity: 0;   left: 8%;  transform: scale(0.7); }
  23%      { opacity: 1;   left: 8%;  transform: scale(1); }
  50%      { opacity: 1;   left: 92%; transform: scale(1); }
  56%      { opacity: 0;   left: 92%; transform: scale(0.8); }
  100%     { opacity: 0;   left: 92%; transform: scale(0.8); }
}

/* The thump's shockwave: a thin ring racing out from centre. */
.ring {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
  border: 2px solid rgba(201, 70, 255, 0.7);
  border-radius: 50%;
  opacity: 0;
  animation: ring var(--ign) ease-out forwards;
}

@keyframes ring {
  0%, 74% { opacity: 0;   transform: scale(0.3); }
  76%     { opacity: 0.7; transform: scale(0.6); }
  100%    { opacity: 0;   transform: scale(9); }
}

/* Lockup reveal. The stepped opacity is the cold-cathode warmup from
   KomarLabsIdent._letter_alpha(): on, dip, on, dip, steady. Paired values
   make each step a hard cut rather than a fade. `backwards` fill is
   deliberate — the element's resting state is visible, so if animations
   never run (print, unsupported, CSS partially applied) the hero still
   shows instead of staying at opacity 0. */
.hero-inner {
  opacity: 1;
  animation: lockup 0.42s steps(1, end) both;
  animation-delay: calc(var(--ign) * 0.78);
  animation-fill-mode: backwards;
}

@keyframes lockup {
  0%   { opacity: 0; }
  1%   { opacity: 0.9; }
  24%  { opacity: 0.9; }
  25%  { opacity: 0.15; }
  40%  { opacity: 0.15; }
  41%  { opacity: 1; }
  64%  { opacity: 1; }
  65%  { opacity: 0.55; }
  80%  { opacity: 0.55; }
  81%  { opacity: 1; }
  100% { opacity: 1; }
}

/* ══════════════════════════ WORK ══════════════════════════ */

.work {
  max-width: 1040px;
  margin: 0 auto;
  padding: 7rem 1.5rem 5rem;
  text-align: center;
}

.cards {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.5rem;
  text-align: left;
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  padding: 2.4rem 2rem 2rem;
  color: inherit;
  transition: border-color 0.2s ease, transform 0.2s ease, background 0.2s ease;
}
.card:hover {
  border-color: var(--accent-dim);
  background: #100e18;
  transform: translateY(-3px);
  text-decoration: none;
}

/* Bracket corners — the logo motif, drawn on hover. */
.card::before, .card::after {
  content: "";
  position: absolute;
  width: 18px;
  height: 18px;
  border: 2px solid var(--accent);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.card::before { top: -1px; left: -1px; border-right: none; border-bottom: none; }
.card::after  { bottom: -1px; right: -1px; border-left: none; border-top: none; }
.card:hover::before, .card:hover::after { opacity: 1; }

.card-kind {
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 0.9rem;
}

.card h3 {
  font-size: 1.6rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  margin-bottom: 0.7rem;
}

.card p {
  color: var(--muted);
  font-size: 0.95rem;
  margin-bottom: 1.6rem;
  flex: 1;
}

.card-link {
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--accent);
  letter-spacing: 0.02em;
}
.card-link::after {
  content: " →";
  transition: opacity 0.2s ease;
  opacity: 0.6;
}
.card:hover .card-link::after { opacity: 1; }


/* ════════════════════════ CONTACT ════════════════════════ */

.contact {
  max-width: 1040px;
  margin: 0 auto;
  padding: 3rem 1.5rem 7rem;
  text-align: center;
}

.contact-line { color: var(--muted); margin-bottom: 1rem; }

.mail {
  display: inline-block;
  font-family: var(--mono);
  font-size: clamp(1.05rem, 3.4vw, 1.6rem);
  color: var(--text);
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--accent-dim);
  transition: color 0.2s ease, border-color 0.2s ease;
}
.mail:hover { color: var(--accent); border-color: var(--accent); text-decoration: none; }

.contact-where {
  margin-top: 1.6rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--faint);
}


/* ═════════════════════════ FOOTER ═════════════════════════ */

footer {
  border-top: 1px solid var(--line);
  padding: 3rem 1.5rem 3.5rem;
  text-align: center;
}

.foot-nav { margin-bottom: 2rem; }
.foot-nav a {
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--muted);
  margin: 0 0.85rem;
  letter-spacing: 0.04em;
}
.foot-nav a:hover { color: var(--accent); }

.legal {
  max-width: 68ch;
  margin: 0 auto 0.7rem;
  font-size: 0.76rem;
  line-height: 1.7;
  color: var(--faint);
}


/* ═══════════════════ CONTENT PAGES (privacy, 404) ═══════════════════ */

.page {
  max-width: 720px;
  margin: 0 auto;
  padding: 5rem 1.5rem 4rem;
}

.back {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 2.5rem;
}
.back:hover { color: var(--accent); }

.page h1 {
  font-size: clamp(1.9rem, 5vw, 2.6rem);
  font-weight: 500;
  letter-spacing: -0.01em;
  margin-bottom: 0.4rem;
}

.updated {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  color: var(--faint);
  margin-bottom: 3rem;
}

.page h2 {
  font-family: var(--mono);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 2.6rem 0 0.8rem;
}

.page p, .page li { color: #b9b5c8; margin-bottom: 0.9rem; font-size: 0.97rem; }
.page ul { padding-left: 1.3rem; }
.page li { margin-bottom: 0.45rem; }

/* Centred minimal page for the 404. */
.page.centered { text-align: center; padding-top: 8rem; min-height: 70svh; }
.page.centered .mark { width: 74px; margin: 0 auto 2rem; display: block; color: var(--accent); }
.page.centered .mark svg { width: 100%; height: auto; display: block;
  filter: drop-shadow(0 0 16px var(--accent-dim)); }


/* ═══════════════════════ RESPONSIVE ═══════════════════════ */

@media (max-width: 760px) {
  .cards { grid-template-columns: 1fr; }
  .work { padding-top: 5rem; }
  .foot-nav a { display: inline-block; margin: 0.3rem 0.6rem; }
}

@media (max-width: 420px) {
  .tagline { letter-spacing: 0.22em; text-indent: 0.11em; }
  .eyebrow { letter-spacing: 0.24em; }
}


/* ════════════════════ REDUCED MOTION ════════════════════
   The ignition is a flashing bright element on a dark field, which is
   exactly what this preference exists to suppress. Everything resolves to
   its settled state immediately: no sweep, no flicker, no ring. */

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

  .scanline, .glint, .ring { display: none; }

  .hero-inner,
  .cue {
    animation: none;
    opacity: 1;
  }
  .cue { opacity: 0.65; }

  .card { transition: none; }
  .card:hover { transform: none; }
}


/* ═══════════════════════════ PRINT ═══════════════════════════ */

@media print {
  body { background: #fff; color: #000; }
  .ignition, .cue { display: none; }
  .lockup img { filter: invert(1); }
  a { color: #000; text-decoration: underline; }
}
