/* davidtschneider.com
 *
 * Palette and typeface carried over from the previous site; the layout is
 * rebuilt. No framework, no JavaScript.
 *
 * The nav is a single element repositioned by the one breakpoint at 62rem:
 * a fixed left sidebar above it, a fixed bottom bar below it. That mirrors the
 * old Bootstrap sidebar/bottombar pair without shipping Bootstrap or jQuery.
 */

/* ---------- fonts ---------- */
/* Latin subset only, self-hosted. Referenced by literal path because build.py
   deliberately does not hash font filenames -- see HASHED_SUFFIXES. */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('/assets/fonts/poppins-300.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/poppins-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/assets/fonts/poppins-600.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fonts/poppins-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- tokens ---------- */
:root {
  --green-dark: #012800;
  --green-bright: #024e00;
  --grey-light: #cfcfcf;
  --rule: #444;

  --bg: var(--grey-light);
  --ink: #101510;
  --ink-muted: #40483f;
  --on-green: var(--grey-light);

  --nav-width: 15rem;
  /* The bottom bar's height must be reserved by .layout as padding, or the
     footer hides behind it. Deriving it from font metrics is fragile, so each
     link gets an explicit row height and the total is computed from it.
     Assumes 6 links in 3 columns => 2 rows; revisit if the nav grows. */
  --bar-row: 2.9rem;
  --bar-height: calc(var(--bar-row) * 2);
  --measure: 42rem;
  --pad-x: clamp(1.25rem, 4vw, 3.5rem);

  --font: 'Poppins', system-ui, -apple-system, 'Segoe UI', sans-serif;
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-weight: 400;
  font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
  line-height: 1.65;
}

img { max-width: 100%; height: auto; }

a { color: var(--green-bright); }
a:hover,
a:focus-visible { color: var(--green-dark); }

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--green-dark);
  color: var(--on-green);
  padding: 0.75rem 1rem;
  z-index: 100;
}
.skip-link:focus {
  left: 0;
}

/* ---------- layout ---------- */
.layout {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  /* Room for the fixed bottom bar on narrow screens. */
  padding-bottom: calc(var(--bar-height) + env(safe-area-inset-bottom, 0px));
}

.main {
  flex: 1;
  width: 100%;
}

/* ---------- nav ---------- */
.sitenav {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--green-dark);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

.sitenav__portrait-link { display: none; }

.sitenav__links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.sitenav__links a {
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--bar-row);
  padding: 0 0.25rem;
  text-align: center;
  color: var(--on-green);
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 400;
  letter-spacing: 0.01em;
}

.sitenav__links a:hover,
.sitenav__links a:focus-visible {
  background: var(--green-bright);
  color: #fff;
}

.sitenav__links a[aria-current='page'] {
  background: var(--green-bright);
  color: #fff;
  font-weight: 600;
}

/* ---------- banner ---------- */
.banner {
  background: var(--green-dark);
  color: var(--on-green);
  padding: clamp(2rem, 6vw, 4rem) var(--pad-x);
}

.banner h1 {
  margin: 0;
  font-weight: 600;
  line-height: 1.15;
  /* clamp() replaces the old vw-sized, nowrap heading, which broke at odd
     viewport sizes. */
  font-size: clamp(1.75rem, 1.2rem + 3.2vw, 3.5rem);
}

/* ---------- content ---------- */
.prose {
  padding: clamp(1.5rem, 4vw, 3rem) var(--pad-x);
  max-width: calc(var(--measure) + 2 * 3.5rem);
}

.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }

.prose h2 {
  font-weight: 600;
  font-size: 1.5rem;
  margin: 2.5rem 0 0.75rem;
}

.prose h3 {
  font-weight: 600;
  font-size: 1.2rem;
  margin: 2rem 0 0.5rem;
}

.prose p { margin: 0 0 1.15rem; }

.prose ul,
.prose ol {
  margin: 0 0 1.15rem;
  padding-left: 1.35rem;
}

.prose li { margin-bottom: 0.4rem; }

.prose blockquote {
  margin: 1.5rem 0;
  padding: 0.25rem 0 0.25rem 1.25rem;
  border-left: 4px solid var(--green-bright);
  color: var(--ink-muted);
  font-weight: 300;
}

.prose code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
  background: rgba(1, 40, 0, 0.08);
  padding: 0.15em 0.35em;
  border-radius: 3px;
}

.prose pre {
  background: var(--green-dark);
  color: var(--on-green);
  padding: 1rem 1.15rem;
  border-radius: 4px;
  overflow-x: auto;
}

.prose pre code {
  background: none;
  padding: 0;
  color: inherit;
}

.prose hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 2.5rem 0;
}

.prose video,
.prose img {
  display: block;
  margin: 1.5rem 0;
  border-radius: 4px;
}

.backlink {
  padding: 1.25rem var(--pad-x) 0;
  margin: 0;
  font-size: 0.9rem;
}

/* The one call-to-action on the site: the link from /portfolio/music-game/ into
   the game itself. Styled as a button because it is the point of that page,
   and everything else in .prose is a body-text link. inline-block rather than
   display:block so it is only as wide as its label at every viewport. */
.prose .playlink {
  margin: 2rem 0 0.75rem;
}

.prose .playlink a {
  display: inline-block;
  padding: 0.7rem 1.6rem;
  background: var(--green-bright);
  color: var(--on-green);
  border-radius: 4px;
  font-weight: 600;
  text-decoration: none;
}

.prose .playlink a:hover,
.prose .playlink a:focus-visible {
  background: var(--green-dark);
  text-decoration: none;
}

.prose .playnote {
  margin: 0;
  font-size: 0.85rem;
  color: var(--ink-muted);
}

/* Bio list on the home page: the one place the old site used a bare list as a
   design element rather than prose. */
.prose .biolist {
  list-style: none;
  padding: 0;
}

.prose .biolist li {
  padding: 0.55rem 0 0.55rem 1.6rem;
  position: relative;
  border-bottom: 1px solid rgba(68, 68, 68, 0.25);
}

.prose .biolist li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 1.15rem;
  width: 0.55rem;
  height: 0.55rem;
  background: var(--green-bright);
}

.contact-email {
  font-size: clamp(1.1rem, 1rem + 1vw, 1.6rem);
  font-weight: 600;
  word-break: break-word;
}

/* ---------- embedded media ---------- */
/* A picture of the page, not an embedded viewer -- see resume_preview.py for
   why. It scrolls with the document like any other image, so none of the
   viewer's sizing constraints apply. */
.resume-preview-link {
  display: block;
  width: min(100%, 950px);
}

.resume-preview {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
  background: #fff;
}

.findscene-logo {
  display: block;
  width: min(100%, 25rem);
  height: auto;
  margin: 0 0 1.5rem;
}

.demo-video {
  display: block;
  width: 100%;
  height: auto;
  max-width: 60rem;
  background: var(--green-dark);
}

/* ---------- portfolio ---------- */
.projects {
  list-style: none;
  margin: 0;
  padding: clamp(1.5rem, 4vw, 3rem) var(--pad-x);
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
  max-width: 70rem;
}

.project {
  border: 1px solid var(--rule);
  border-left: 5px solid var(--green-dark);
  background: rgba(255, 255, 255, 0.35);
  padding: 1.25rem 1.4rem;
}

.project h2 {
  margin: 0 0 0.35rem;
  font-size: 1.2rem;
  font-weight: 600;
  line-height: 1.3;
}

.project h2 a { text-decoration: none; }
.project h2 a:hover,
.project h2 a:focus-visible { text-decoration: underline; }

.project__status {
  margin: 0 0 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
}

.project__blurb {
  margin: 0;
  font-weight: 300;
}

/* ---------- footer ---------- */
.footer {
  padding: 2rem var(--pad-x);
  border-top: 1px solid rgba(68, 68, 68, 0.3);
  color: var(--ink-muted);
  font-size: 0.85rem;
}

.footer p { margin: 0; }

/* ---------- wide screens ---------- */
@media (min-width: 62rem) {
  .layout {
    margin-left: var(--nav-width);
    padding-bottom: 0;
  }

  .sitenav {
    top: 0;
    right: auto;
    width: var(--nav-width);
    height: 100vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.5rem;
    padding: 2rem 0;
    /* The banner is the same green, so without this the sidebar and the banner
       merge into a single shape at the top of the page. */
    border-right: 1px solid rgba(207, 207, 207, 0.22);
  }

  .sitenav__portrait-link {
    display: block;
    width: 70%;
  }

  .sitenav__portrait {
    display: block;
    width: 100%;
    height: auto;
  }

  .sitenav__links {
    display: block;
    width: 100%;
  }

  /* A document preview is not prose, so it opts out of .prose's measure cap.
     Clamped to the viewport so it never forces a horizontal scrollbar. */
  .resume-preview-link {
    width: min(950px, calc(100vw - var(--nav-width) - 2 * var(--pad-x)));
  }

  .sitenav__links a {
    /* Undo the fixed-height flex row used by the mobile bar. */
    display: block;
    height: auto;
    text-align: left;
    padding: 0.6rem 1.5rem;
    font-size: 1rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
