@font-face {
  font-family: 'CommitMono';
  src: url('fonts/CommitMono-VF.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
}

@font-face {
  font-family: 'Inter';
  src: url('fonts/Inter-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
}

@font-face {
  font-family: 'PP Editorial Old';
  src: url('fonts/PPEditorialOld-Regular.otf') format('opentype');
  font-weight: 400;
  font-style: normal;
}

@font-face {
  font-family: 'PP Editorial Old';
  src: url('fonts/PPEditorialOld-Italic.otf') format('opentype');
  font-weight: 400;
  font-style: italic;
}

@font-face {
  font-family: 'PP Editorial Old';
  src: url('fonts/PPEditorialOld-Ultralight.otf') format('opentype');
  font-weight: 200;
  font-style: normal;
}

@font-face {
  font-family: 'PP Editorial Old';
  src: url('fonts/PPEditorialOld-UltralightItalic.otf') format('opentype');
  font-weight: 200;
  font-style: italic;
}

@font-face {
  font-family: 'PP Editorial Old';
  src: url('fonts/PPEditorialOld-Ultrabold.otf') format('opentype');
  font-weight: 800;
  font-style: normal;
}

@font-face {
  font-family: 'PP Editorial Old';
  src: url('fonts/PPEditorialOld-UltraboldItalic.otf') format('opentype');
  font-weight: 800;
  font-style: italic;
}

@font-face {
  font-family: 'IBM Plex Sans';
  src: url('fonts/IBMPlexSans-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
}

@font-face {
  font-family: 'IBM Plex Sans';
  src: url('fonts/IBMPlexSans-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  cursor: none;
}

/* color-scheme:light + an explicit html background stop the browser from
   painting its dark-mode default (black, on macOS Chrome) into the
   rubber-band overscroll area when a visitor on a dark-mode system
   scrolls past the top/bottom of a page. */
html {
  height: 100%;
  background: #fcfcfc;
  color-scheme: light;
}

body {
  height: 100%;
}

body {
  background: #fcfcfc;
  overflow: hidden;
}

/* nav bar: spans full window width, fixed 45px height, fixed 30px right padding, fixed 20px gaps */
.nav-bar {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 45px;
  background: #fcfcfc;
  border-bottom: 1px solid rgba(148, 148, 148, 0.25);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 30px;
  z-index: 10;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 20px;
}

.nav-link {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'CommitMono', monospace;
  font-weight: 400;
  font-size: 12px;
  color: #7b7b7b;
  text-decoration: none;
  white-space: nowrap;
}

/* opt-in modifier: pushes the nav-links cluster to the right and leaves
   room for a brand mark on the left (only the home page uses this). */
.nav-bar.has-brand {
  justify-content: space-between;
  padding-left: 30px;
}

.nav-brand {
  font-family: 'CommitMono', monospace;
  font-weight: 400;
  font-size: 12px;
  color: #7b7b7b;
  text-decoration: none;
  white-space: nowrap;
}

/* custom cursor: an orange dot everywhere on the site.
   Positioned via JS on every mousemove. */
#custom-cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: 9999;
}

.cursor-dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 21px;
  height: 21px;
  transform: translate(-50%, -50%) scale(1);
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.15s ease;
  opacity: 0; /* hidden until the first real mousemove positions it — see
                 shared.js — otherwise it flashes at the top-left corner
                 (its default 0,0 position) on every page load */
}

/* touch devices have no real mousemove, but iOS/Android browsers fire one
   synthetic "ghost" mousemove at the tapped point right after a touchstart
   — enough to trigger the opacity:0 → 1 reveal above, leaving the dot
   stranded at whatever was last tapped since nothing ever moves it again.
   There's no mouse pointer to represent here at all, so hide it outright. */
@media (hover: none) and (pointer: coarse) {
  #custom-cursor {
    display: none;
  }
}

/* IBM eye-bee-M rebus icons (Figma "ibm" frame) — percentage-based so the
   composition scales cleanly whether it's sitting in the small home-page
   work-card cover or the wider case-study cover. */
.ibm-icons {
  position: absolute;
  left: 18.43%;
  top: 34.8%;
  width: 63.34%;
  height: 30.29%;
  display: flex;
  align-items: flex-end;
}

.ibm-icon-eye {
  width: 28.12%;
  height: auto;
}

.ibm-icon-bee {
  width: 42.82%;
  height: auto;
}

.ibm-icon-m {
  width: 29.06%;
  height: auto;
}

/* site footer: Figma "footer" (node 1678:5531). Made to match the nav bar
   exactly — full window width, 45px min height, same #fcfcfc fill and the
   same hairline stroke, just on the top edge here (the edge that faces the
   page content) so the two bookend the page consistently. The left note
   and the right link cluster are each held a constant 30px off the
   viewport edge by 30px side padding on a space-between flex row, so the
   insets never change with window size.

   Both pieces are nowrap; on a narrow window they can't share one line and
   space-between would then push the link cluster off the right edge — a
   phantom horizontal scroll / dead strip to the right of every page. So
   the row is allowed to wrap (links drop to their own line, still 30px in
   via the padding); below 560px it stops being a row at all — see the
   media query under .site-footer-fixed. Desktop layout is unchanged. */
.site-footer {
  position: relative;
  z-index: 6; /* sit above the case-study pages' fixed outline sidebar (z-index 5) */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 20px;
  width: 100%;
  min-height: 45px;
  padding: 0 30px;
  background: #fcfcfc;
  border-top: 1px solid rgba(148, 148, 148, 0.25);
}

.site-footer-note,
.site-footer-link {
  font-family: 'CommitMono', monospace;
  font-weight: 400;
  font-size: 12px; /* matches the nav bar's .nav-link */
  color: #7b7b7b; /* matches the nav bar's .nav-link */
  white-space: nowrap;
}

.site-footer-links {
  display: flex;
  align-items: center;
  gap: 20px;
}

.site-footer-link {
  text-decoration: none;
}

.site-footer-link:hover {
  color: #ff7800;
}

/* about page: that page is a fixed, non-scrolling 100vh canvas. The footer
   is pinned to the bottom 45px of the viewport and about.css shortens
   .page to calc(100vh - 45px) so the sidebar + game sit flush on top of it
   (no overlap, no scroll). about.css drops this back to static at its
   mobile breakpoint, where the page does scroll. */
.site-footer-fixed {
  position: fixed;
  left: 0;
  bottom: 0;
  height: 45px;
  z-index: 10;
}

/* phone widths: past the point where the note + links start to crowd, drop
   the space-between row entirely and stack it — note on top, then every
   link on its own line, all left-aligned to the same 30px gutter. (On the
   about page this range is already past its own 900px breakpoint, where
   the footer has gone back to static/auto-height, so the stack has room.) */
@media (max-width: 560px) {
  .site-footer {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    padding-top: 18px;
    padding-bottom: 18px;
  }

  .site-footer-links {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
}
