/* Black Dragon Lab.
 *
 * Dark by commitment, not preference: the mark is white on black with no
 * light-ground variant, and inverting a logo is how you make it look wrong.
 *
 * Two rules this page never breaks. Everything sits on one left axis — the
 * previous version centred the logo above left-aligned text, which reads as
 * an accident rather than a choice. And the structural device is the hairline
 * rule, taken from the wordmark itself, where two rules flank the word LAB.
 */

:root {
  color-scheme: dark;

  --ground: #05070a;
  --text:   #eef2f5;
  --muted:  #97a3af;
  --dim:    #616d78;
  --rule:   #1e262f;
  --hair:   #2b3540;   /* one step up, for rules that must be noticed */

  /* Type scale. Nothing on the page is off it. */
  --t-xs: 11px;
  --t-sm: 13px;
  --t-md: 17px;
  --t-lg: 21px;

  /* Spacing scale. Sections breathe; things inside a section do not. */
  --s-1: 6px;
  --s-2: 12px;
  --s-3: 20px;
  --s-4: 32px;
  --s-5: 56px;
  --s-6: 88px;

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  padding: 0 28px var(--s-6);
  background: var(--ground);
  color: var(--text);
  font: var(--t-md)/1.7 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* One column, one axis. 40rem keeps prose near 70 characters. */
.wrap { max-width: 40rem; margin: 0 auto; }

/* --- Navigation ------------------------------------------------------- */

.nav {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex-wrap: wrap;
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--rule);
}

.nav .home { display: flex; line-height: 0; border: 0; }
.nav .home img { height: 26px; width: auto; }

.nav .links {
  margin-left: auto;
  display: flex;
  gap: var(--s-3);
  font: var(--t-sm)/1 var(--mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.nav a { color: var(--dim); border: 0; }
.nav a:hover, .nav a:focus-visible { color: var(--text); }
.nav a[aria-current="page"] { color: var(--muted); }

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

/* Left, like everything else. The lockup is the largest thing on the page,
   so it sets the axis rather than floating free of it. */
.hero {
  padding: var(--s-6) 0 var(--s-5);
  border-bottom: 1px solid var(--rule);
}

.hero img { width: min(100%, 22rem); height: auto; display: block; }

/* --- Type ------------------------------------------------------------- */

/* Echoes the wordmark: uppercase, widely tracked, small. For labels and
   metadata, never for reading. */
.eyebrow {
  font: 500 var(--t-xs)/1 var(--mono);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dim);
  margin: var(--s-5) 0 var(--s-2);
}

h1 {
  font-size: clamp(31px, 5.4vw, 43px);
  line-height: 1.14;
  letter-spacing: -0.025em;
  font-weight: 600;
  text-wrap: balance;
  margin: 0 0 var(--s-3);
}

/* A rule above every section heading — the wordmark's own device, and it
   gives the page a rhythm that spacing alone did not. */
h2 {
  font: 500 var(--t-xs)/1 var(--mono);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dim);
  margin: var(--s-6) 0 var(--s-3);
  padding-top: var(--s-3);
  border-top: 1px solid var(--rule);
}

h3 {
  font-size: var(--t-md);
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 var(--s-1);
}

p { margin: 0 0 var(--s-3); }
ul { padding-left: 20px; margin: 0 0 var(--s-3); }
li { margin-bottom: var(--s-1); }

.lede {
  font-size: var(--t-lg);
  line-height: 1.55;
  color: var(--muted);
  letter-spacing: -0.01em;
  margin-bottom: var(--s-4);
}

.updated {
  font: var(--t-sm)/1 var(--mono);
  color: var(--dim);
  margin: 0 0 var(--s-5);
}

/* Monochrome. The mark has no colour in it, so a coloured accent was
   decoration rather than a decision; links carry their own affordance. */
a {
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid var(--hair);
}

a:hover, a:focus-visible { border-bottom-color: var(--text); }

/* --- Projects, as ruled rows rather than boxes ------------------------- */

.card {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-4) 0;
  border: 0;
  border-top: 1px solid var(--rule);
  color: inherit;
}

.card:last-of-type { border-bottom: 1px solid var(--rule); }
a.card:hover, a.card:focus-visible { border-color: var(--hair); }

.card img {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  flex: none;
  background: #000;
  border: 1px solid var(--rule);
}

.card .body { min-width: 0; }

.card .meta {
  font: var(--t-xs)/1 var(--mono);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 var(--s-1);
}

.card p:last-child {
  margin-bottom: 0;
  color: var(--muted);
  font-size: 16px;
}

/* Project pages lead with their own mark. */
.project-mark {
  width: 52px;
  height: 52px;
  border-radius: 12px;
  background: #000;
  border: 1px solid var(--rule);
  margin: var(--s-6) 0 0;
  display: block;
}

.note {
  border-left: 1px solid var(--hair);
  padding: var(--s-1) 0 var(--s-1) var(--s-3);
  margin: var(--s-4) 0;
  color: var(--muted);
}

.note p:last-child { margin-bottom: 0; }

hr { border: 0; border-top: 1px solid var(--rule); margin: var(--s-5) 0; }

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

footer {
  border-top: 1px solid var(--rule);
  margin-top: var(--s-6);
  padding-top: var(--s-3);
  font: var(--t-sm)/1.6 var(--mono);
  color: var(--dim);
  display: flex;
  gap: var(--s-3);
  flex-wrap: wrap;
}

footer a { color: var(--dim); border-bottom-color: transparent; }
footer a:hover { color: var(--text); border-bottom-color: var(--hair); }
footer .spacer { margin-left: auto; }

code {
  font: 15px/1 var(--mono);
  border: 1px solid var(--rule);
  padding: 1px 5px;
  border-radius: 4px;
}

@media (max-width: 32rem) {
  .hero { padding-top: var(--s-5); }
  .card { flex-direction: column; gap: var(--s-2); }
  footer .spacer { margin-left: 0; }
}

/* --- The product, on a device ------------------------------------------
 *
 * A page about an app that never shows the app is asking to be taken on
 * trust. The frame is drawn in CSS rather than composited into the image,
 * so the screenshot underneath stays a plain screenshot — replaceable
 * without a designer, and still legible if styles fail to load.
 */

.showcase {
  display: grid;
  grid-template-columns: 1fr minmax(0, 15rem);
  gap: var(--s-5);
  align-items: center;
  padding: var(--s-5) 0;
}

.showcase .words { min-width: 0; }
.showcase .words > :first-child { margin-top: 0; }
.showcase .words h2 { border-top: 0; padding-top: 0; margin-top: 0; }

.device {
  position: relative;
  border-radius: 40px;
  padding: 8px;
  background: linear-gradient(160deg, #39434e, #10151b 42%, #222b34);
  box-shadow: 0 30px 70px -30px rgba(0, 0, 0, 0.9),
              0 0 0 1px rgba(255, 255, 255, 0.05);
  justify-self: end;
  width: 100%;
}

.device img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 33px;
}

/* Alternating sides, so a column of these does not march down one edge. */
.showcase.flip { grid-template-columns: minmax(0, 15rem) 1fr; }
.showcase.flip .device { order: -1; justify-self: start; }

@media (max-width: 44rem) {
  .showcase,
  .showcase.flip { grid-template-columns: 1fr; gap: var(--s-4); }
  .showcase .device,
  .showcase.flip .device {
    order: 0;
    justify-self: center;
    max-width: 16rem;
  }
}

/* Reveal on scroll, in CSS. The content security policy forbids scripts
 * outright, so a JavaScript parallax was never an option here — and this
 * costs nothing, degrades to "always visible" in browsers without
 * scroll-driven animations, and honours a reduced-motion preference.
 */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .showcase, .card {
      animation: rise linear both;
      animation-timeline: view();
      animation-range: entry 10% cover 32%;
    }
    @keyframes rise {
      from { opacity: 0; transform: translateY(26px); }
      to   { opacity: 1; transform: none; }
    }
  }
}
