/* =====================================================================
   lizatyl.com — Design Kit implementation
   Minimal · state-of-the-art · engineered. Monochrome + one orange.
   ===================================================================== */

:root {
  --paper:    #ffffff;   /* background — crisp white           */
  --ink:      #0e0e10;   /* primary text (near-black)          */
  --graphite: #6b6b70;   /* secondary text                     */
  --hairline: #e6e6e8;   /* rules, grid                        */
  --orange:   #ff5a1f;   /* the moving line + key accents      */
  --mist:     #c4c4c9;   /* grey echo line / placeholders      */
  --placeholder-bg: #ededef;

  --font-display: "Michroma", "Segoe UI", sans-serif;
  --font-body:    "Inter", "Segoe UI", sans-serif;
  --font-mono:    "Space Mono", ui-monospace, monospace;

  --gutter: clamp(24px, 5vw, 72px);
  --header-h: 84px;
}

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

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

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: inherit; text-decoration: none; }

/* Home aims to be a single screen; it scrolls only if the viewport is
   too short for the hero + footer (the line is position:fixed, so it
   stays framed either way). */
.page-home { min-height: 100vh; }

/* ---- shared type helpers ------------------------------------------- */
.label {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--graphite);
  margin: 0;
}
.label--accent { color: var(--orange); }

.link {
  color: var(--orange);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease;
}
.link:hover { border-bottom-color: var(--orange); }

/* =====================================================================
   Header
   ===================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 22px var(--gutter);
  border-bottom: 1px solid var(--hairline);
  background: transparent;
}
/* On subpages there is no canvas behind, so a solid bar keeps it crisp */
.page-sub .site-header { background: var(--paper); }
/* Home has no wordmark — the H1 is the name — so the nav takes the right. */
.page-home .site-header { justify-content: flex-end; }

.wordmark {
  font-family: var(--font-display);
  font-size: clamp(22px, 2.6vw, 30px);
  letter-spacing: 0.02em;
  color: var(--ink);
  line-height: 1;
  white-space: nowrap;
}

.nav {
  display: flex;
  align-items: center;
  gap: clamp(16px, 2.2vw, 36px);
}
.nav a {
  font-family: var(--font-display);
  font-size: clamp(11px, 1vw, 13px);
  letter-spacing: 0.06em;
  color: var(--graphite);
  transition: color 0.2s ease;
  white-space: nowrap;
}
.nav a:hover,
.nav a:focus-visible { color: var(--ink); }
.nav a.is-active { color: var(--orange); }

/* mobile nav toggle (hidden on desktop) */
.nav-toggle {
  display: none;
  appearance: none;
  background: none;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  padding: 8px 12px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.16em;
  color: var(--ink);
  cursor: pointer;
}

@media (max-width: 1080px) {
  .nav-toggle { display: block; }
  .nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--paper);
    border-bottom: 1px solid var(--hairline);
    padding: 8px var(--gutter) 16px;
  }
  .nav.is-open { display: flex; }
  .nav a { padding: 12px 0; font-size: 13px; }
}

/* =====================================================================
   Generative line (canvas) — full-bleed behind everything (home only)
   ===================================================================== */
.generative {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  z-index: 0;
  pointer-events: none;
  display: block;
  /* Own GPU layer so drift/mouse are pure compositor transforms — the
     canvas is drawn ONCE and never repainted per frame. */
  will-change: transform;
}

/* Static gradient that fades the line out over the left text column.
   Painted once (never animated) so it costs the compositor nothing. */
.generative-fade {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(
    to right,
    var(--paper) 0%,
    var(--paper) 10%,
    rgba(255, 255, 255, 0) 34%
  );
}

/* =====================================================================
   Home — hero (photo · name · tagline · social icons)
   ===================================================================== */
.hero {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  align-items: center;
  /* Extra room at the foot pulls the centred block up off the middle —
     it sits a little above centre, which reads better than dead-centre on
     a page with no footer. Short viewports drop this again (see the
     max-height rules) so the page still fits without scrolling. */
  padding: clamp(20px, 3vh, 52px) var(--gutter) clamp(56px, 10vh, 150px);
}
.hero-profile { max-width: 820px; }
.headshot-col {
  display: inline-block;
  text-align: center;
  margin-top: 26px;
}
/* Round medallion — shared by the home hero and the About page, so the two
   portraits are the same object and are cropped by the same numbers. The
   photo is a cutout on paper, so the disc carries its own paper fill and
   any uncovered sliver is invisible. Only the size and the halo differ
   between the two, set on each below. */
.headshot,
.portrait-disc {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  overflow: hidden;
  background: var(--paper);
  border: 1px solid var(--hairline);
}
/* Framed on the face, not on the file. Her head sits high and right of
   centre in the source (bbox x 218-620, y 43-510 of 698x800), so the image
   is scaled to 107.6% and offset to bring the head's centre to the middle
   of the disc, a touch above the horizontal axis. Re-derive these three
   numbers if the source photo is ever replaced. */
.headshot img,
.portrait-disc img {
  display: block;
  position: absolute;
  width: 107.6%;
  height: auto;
  left: -14.6%;
  top: 3.4%;
}
.headshot {
  /* auto, not 0: .headshot-col is only as wide as the icon row, and
     text-align cannot centre a block — so the disc sits over the icons
     at every width, including the centred mobile layout. */
  margin: 0 auto;
  width: clamp(150px, 16vw, 210px);
  box-shadow: 0 0 0 4px var(--paper), 0 6px 18px rgba(14, 14, 16, 0.07);
}
.hero-name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(32px, 4.2vw, 60px);
  line-height: 1.12;
  color: var(--ink);
  /* The name opens the hero, so it carries no leading space. The negative
     left margin is optical alignment, not layout: the three hero lines use
     three different faces, and Michroma's left side bearing on the L is
     0.074em while Space Mono's on the M is 0. Stated in em so the
     correction tracks the clamped font size. */
  margin: 0 0 0 -0.074em;
}
/* the affiliation now sits under the tagline, above the portrait */
.hero-profile .label--accent { margin-top: 18px; }
.hero-sub {
  font-family: var(--font-body);
  font-size: clamp(17px, 1.6vw, 21px);
  color: var(--graphite);
  margin: 16px 0 0 -0.06em;   /* optical alignment — Inter's R, see .hero-name */
  max-width: 34ch;
}

/* ---- social icon row ------------------------------------------------ */
.social-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(12px, 1.6vw, 20px);
  margin-top: 32px;
}
.social {
  display: inline-flex;
  color: var(--graphite);
  transition: color 0.2s ease;
}
.social svg { width: 26px; height: 26px; }
.social:hover,
.social:focus-visible { color: var(--orange); }
.social--disabled { color: var(--hairline); cursor: default; }
.social--disabled:hover { color: var(--hairline); }

/* image-based brand marks (MQ crest is multi-colour, so it can't use
   currentColor): greyscaled to sit in the monochrome row, true colours
   on hover — the same "one accent on interaction" logic as the rest. */
.social--img img {
  height: 26px;
  width: auto;
  display: block;
  filter: grayscale(1) opacity(0.62);
  transition: filter 0.2s ease;
}
.social--img:hover img,
.social--img:focus-visible img { filter: none; }

.social-row--footer { justify-content: flex-start; margin-top: 14px; }
.social-row--footer .social svg { width: 22px; height: 22px; }
.social-row--footer .social--img img { height: 22px; }

/* =====================================================================
   Subpages — shared page scaffold
   ===================================================================== */
.page-main {
  position: relative;
  z-index: 1;
  flex: 1;
  padding: clamp(40px, 7vh, 96px) var(--gutter);
}
.page-inner { max-width: 1240px; }
.page-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(40px, 5vw, 68px);
  line-height: 1.05;
  color: var(--ink);
  margin: 14px 0 30px;
}
.section-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(22px, 2.4vw, 32px);
  line-height: 1.25;
  color: var(--ink);
  margin: 56px 0 18px;
}
.prose {
  font-family: var(--font-body);
  font-size: clamp(15px, 1.2vw, 17px);
  line-height: 1.62;
  color: var(--ink);
  max-width: 66ch;
  margin: 0 0 22px;
}
.prose--narrow { max-width: 40ch; }

/* =====================================================================
   About
   ===================================================================== */
.about-grid {
  display: grid;
  grid-template-columns: minmax(220px, 380px) minmax(0, 1fr);
  gap: clamp(40px, 7vw, 110px);
  align-items: start;
  max-width: 1240px;
}
.portrait {
  margin: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.portrait--card {
  width: 100%;
  flex-direction: column;
  align-items: stretch;
  background: transparent;
}
/* the About disc is the plain version — a hairline circle, no halo */
.portrait-disc {
  width: 100%;
  max-width: 340px;
}
.portrait-caption {
  align-self: flex-start;
  margin-top: 18px;
}
.about-body { padding-top: 4px; }

.meta { margin: 34px 0 0; }
.meta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px 14px;
  padding: 6px 0;
}
.meta-row dt { margin: 0; }
.meta-row dd {
  margin: 0;
  /* full basis puts every value on its own line under its label, so CONTACT
     reads the same way the longer RESEARCH row already did when it wrapped */
  flex-basis: 100%;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.02em;
  color: var(--graphite);
}

/* =====================================================================
   Teaching — pull quote + testimonial slider
   ===================================================================== */
.pullquote {
  margin: 26px 0 10px;
  padding: 4px 0 4px 26px;
  border-left: 3px solid var(--orange);
  max-width: 72ch;
}
.pullquote p {
  font-family: var(--font-body);
  /* same scale as .prose — both the quote and its citation sit at body size */
  font-size: clamp(15px, 1.2vw, 17px);
  line-height: 1.6;
  color: var(--ink);
  margin: 0;
}
/* testimonial voice: quoted body in italics, sign-off upright with the
   name and the role on their own lines, air between the two. */
.pullquote > p:first-child,
.slide > p:first-child { font-style: italic; }

.quote-attrib {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.04em;
  color: var(--graphite);
  font-style: normal;
  margin: 20px 0 0;
}
.quote-attrib .t-name {
  display: block;
  font-weight: 400;
  color: var(--ink);
  margin-bottom: 2px;
}
.pullquote .quote-attrib { padding-left: 0; }
/* .pullquote p / .slide p reset margins at higher specificity — restore
   the breathing room above the sign-off explicitly at the same level. */
.pullquote p.quote-attrib,
.slide p.quote-attrib { margin-top: 20px; }

.slider {
  position: relative;
  max-width: 860px;
  margin-top: 26px;
  border: 1px solid var(--hairline);
  border-radius: 6px;
  padding: clamp(22px, 3vw, 40px) clamp(22px, 3.5vw, 56px) 64px;
}
.slider-viewport { overflow: hidden; }
.slider-track {
  display: flex;
  align-items: flex-start;
  transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1);
}
.slide { flex: 0 0 100%; min-width: 0; padding-right: 2px; }
.slide p {
  font-family: var(--font-body);
  /* same scale as .prose — the testimonials read as body copy, not display */
  font-size: clamp(15px, 1.2vw, 17px);
  line-height: 1.62;
  color: var(--ink);
  margin: 0;
}
.slider-controls {
  position: absolute;
  left: clamp(22px, 3.5vw, 56px);
  right: clamp(22px, 3.5vw, 56px);
  bottom: 18px;
  display: flex;
  align-items: center;
  gap: 16px;
}
.slider-btn {
  appearance: none;
  background: none;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 14px;
  line-height: 1;
  padding: 8px 14px;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.slider-btn:hover,
.slider-btn:focus-visible { border-color: var(--orange); color: var(--orange); }
.slider-dots { display: flex; gap: 8px; margin-left: auto; }
.slider-dot {
  appearance: none;
  border: none;
  background: var(--hairline);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  transition: background 0.2s ease;
}
.slider-dot.is-active { background: var(--orange); }
.slider-status {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--graphite);
}

/* =====================================================================
   Research — project rows  ·  Café — episode rows
   ===================================================================== */
.item-row {
  display: grid;
  grid-template-columns: minmax(240px, 400px) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
  padding: 40px 0;
  border-top: 1px solid var(--hairline);
  max-width: 1100px;
}
.item-row:first-of-type { border-top: none; }

/* Rotating photo set inside a project row. Reuses the [data-slider] engine,
   stripped of the testimonial card's border and padding — the photographs
   are the frame. The credit line sits inside each slide, so attribution
   travels with the image it belongs to and can never drift out of sync. */
.media-slider {
  max-width: none;
  margin-top: 0;
  border: none;
  border-radius: 0;
  padding: 0 0 36px;
}
.media-slider .slide img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 6px;
  background: var(--placeholder-bg);
}
p.media-credit {
  font-family: var(--font-body);
  font-style: italic;
  font-size: 13px;
  line-height: 1.45;
  color: var(--graphite);
  margin: 10px 0 0;
}
.media-slider .slider-controls { left: 0; right: 0; bottom: 0; gap: 10px; }
.media-slider .slider-btn { padding: 5px 11px; font-size: 12px; }

/* ---- Project 01 — the video ------------------------------------------
   Square source (1080x1080). The file was rewritten with its moov atom
   ahead of mdat, so playback can start on a short prefix rather than the
   whole 27 MB; preload="metadata" then costs the visitor almost nothing
   until they press play. */
.item-video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  border-radius: 6px;
  background: var(--ink);
}

.media-placeholder {
  width: 100%;
  aspect-ratio: 16 / 10;
  background: var(--placeholder-bg);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.item-media { margin: 0; }
.item-media .label { text-align: center; }
/* Café episodes play in place. youtube-nocookie is the privacy-preserving
   host: no tracking cookie is set unless the visitor actually presses play.
   lazy-loading keeps three players off the critical path. */
.video-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 6px;
  overflow: hidden;
  background: var(--ink);
}
.video-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.item-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(19px, 2vw, 26px);
  line-height: 1.3;
  color: var(--ink);
  margin: 4px 0 14px;
}
.item-title a { transition: color 0.2s ease; }
.item-title a:hover { color: var(--orange); }

.ref-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
}
.ref-list li {
  font-family: var(--font-body);
  font-size: clamp(15px, 1.25vw, 17px);
  line-height: 1.55;
  color: var(--graphite);
  padding: 6px 0 6px 18px;
  position: relative;
}
.ref-list li::before {
  content: "•";
  position: absolute;
  left: 0;
  color: var(--orange);
}

/* =====================================================================
   Footer — contact, on every page
   ===================================================================== */
.site-footer {
  position: relative;
  z-index: 1;
  padding: 34px var(--gutter) 26px;
  border-top: 1px solid var(--hairline);
  background: transparent;
}
.page-sub .site-footer { background: var(--paper); }

.footer-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 40px clamp(48px, 8vw, 140px);
  padding-bottom: 26px;
}
.footer-note {
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--ink);
  margin: 10px 0 12px;
}
.footer-contact .link {
  font-family: var(--font-mono);
  font-size: 15px;
  display: inline-block;
  margin-top: 10px;
}
.footer-mark {
  font-family: var(--font-display);
  font-size: clamp(12px, 1.1vw, 15px);
  letter-spacing: 0.06em;
  color: var(--ink);
}

/* =====================================================================
   Responsive
   ===================================================================== */
@media (max-width: 760px) {
  .about-grid,
  .item-row { grid-template-columns: 1fr; }
  /* single column: the portrait stacks above the text, centred with it */
  .portrait--card { max-width: 320px; margin-inline: auto; }
  .portrait-caption { align-self: center; }
  .item-media { max-width: 440px; }

  /* Phones: the name and portrait sit centred at the top of the screen,
     and the generative line is pushed down so it reads as sitting below
     them rather than behind them. Only `top` moves — height stays 100vh,
     so the figure is never squashed (the script strokes it at viewport
     size and knows nothing about this offset). */
  .hero { align-items: flex-start; padding-top: 16px; }
  .hero-profile { justify-content: center; text-align: center; margin-inline: auto; }
  .hero-sub { margin-left: auto; margin-right: auto; }
  /* the optical left-edge correction is meaningless once centred */
  .hero-name { margin-left: 0; }

  /* keep the line as a calm backdrop on small screens */
  .generative { opacity: 0.9; top: 22vh; }
  /* eight icons have to fit 320px-wide phones without stealing the gutter */
  .social-row { gap: 8px; }
}

/* The home page is meant to be one screen and never scroll. On a short
   viewport the portrait and the vertical rhythm give up room first — the
   name and the links keep their size. */
@media (max-height: 760px) {
  /* keep some of the foot padding so the block still sits above centre —
     there is slack below it even here, it is the top that runs out */
  .hero { padding-top: 12px; padding-bottom: clamp(36px, 7vh, 80px); }
  .headshot { width: clamp(104px, 13vw, 150px); }
  .headshot-col { margin-top: 14px; }
  .social-row { margin-top: 18px; }
  .hero-profile .label--accent { margin-top: 12px; }
  .hero-sub { margin-top: 10px; }
}
@media (max-height: 620px) {
  .headshot { width: clamp(80px, 11vw, 112px); }
  .headshot-col { margin-top: 10px; }
  .social-row { margin-top: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .link, .slider-track, .social, .social--img img { transition: none; }
}
