  * { box-sizing: border-box; }
  html, body { margin: 0; padding: 0; background: #161616; }
  body { display: flex; justify-content: center; overflow-x: auto; position: relative; }
  a { color: inherit; text-decoration: none; }
  * { box-sizing: border-box; margin: 0; padding: 0; }
  .c { width: 1440px; background: #161616; color: #f2f2f0; font-family: "Plus Jakarta Sans", -apple-system, sans-serif; position: relative; overflow: hidden; }
  /* z-index:2 here (and on .footer, .eyebrow-row below, plus page-specific
     content wrappers on about.html/contact.html) keeps real page content
     above js/particles.js's canvas, which prepends itself into .c at
     position:fixed; z-index:1 -- without an explicit z-index these plain,
     non-positioned elements would otherwise paint underneath it. */
  /* Same blob-glow recipe as the homepage (see css/homepage.css for the
     full rationale): .blob-layer is a body-level sibling of .c, position:
     fixed and sized/parallax-scrolled by js/particles.js in lockstep with
     its dot canvas, so its glow reaches the true page edges on a wide
     viewport instead of stopping at .c's 1440px column, clipped by
     overflow:hidden right at that edge. Base rules live here since more
     than one page now uses them (about.html, contact.html); each page
     with blobs overrides .c's background to none below so the glow shows
     through the content column too, not just the margins beside it. */
  .blob-layer { position: fixed; top: 0; left: 0; width: 100%; overflow: hidden; pointer-events: none; z-index: 0; }
  .blob { position: absolute; border-radius: 50%; opacity: 0.22; }
  .nav { display: flex; align-items: center; justify-content: space-between; padding: 34px 56px; border-bottom: 1px solid rgba(255,255,255,0.08); position: relative; z-index: 2; }
  .nav .logo { font-size: 16px; font-weight: 800; letter-spacing: -0.01em; color: #fff; transition: opacity .2s ease; }
  .nav .logo:hover { opacity: 0.8; }
  .nav .logo span { color: #00d4ff; }
  .nav .back { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: rgba(255,255,255,0.7); text-decoration: none; }
  .nav .back:before { content: "←"; color: #00d4ff; }
  .nav .links { display: flex; align-items: center; gap: 30px; font-size: 13px; font-weight: 600; color: rgba(255,255,255,0.7); }
  .nav .links a { transition: color .2s ease; }
  .nav .links a:hover { color: #fff; }
  .nav .links .current { color: #fff; }
  html[data-pw-mode="fade"] .nav .links a, html[data-pw-mode="fade"] .nav .links .current { transition: color .6s ease; }
  html[data-pw-mode="fade"] .nav .links .current { color: rgba(255,255,255,0.7); }
  html[data-pw-mode="fade"][data-pw-revealed="1"] .nav .links .current { color: #fff; }
  @media (prefers-reduced-motion: reduce) {
    html[data-pw-mode="fade"] .nav .links .current { transition: none !important; color: #fff !important; }
  }
  .hero .play { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 78px; height: 78px; border-radius: 50%; background: rgba(20,20,20,0.55); border: 2px solid rgba(255,255,255,0.7); backdrop-filter: blur(4px); display: flex; align-items: center; justify-content: center; transition: transform .2s ease, background .2s ease; }
  .hero:hover .play { transform: translate(-50%, -50%) scale(1.08); background: rgba(0,136,255,0.55); }
  .hero .play:before { content: ""; border-style: solid; border-width: 12px 0 12px 20px; border-color: transparent transparent transparent #fff; margin-left: 5px; }
  .hero .vidtag { position: absolute; bottom: 18px; left: 18px; background: rgba(20,20,20,0.7); backdrop-filter: blur(6px); border: 1px solid rgba(255,255,255,0.14); padding: 6px 13px; border-radius: 999px; font-size: 11.5px; font-weight: 700; color: rgba(255,255,255,0.75); }
  .hero.playing img { display: none; }
  .hero iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }
  .hero.playing .play, .hero.playing .vidtag { opacity: 0; pointer-events: none; }
  .hero .play, .hero .vidtag { transition: opacity .25s ease; }
  .metarow { display: flex; align-items: center; justify-content: space-between; margin-top: 34px; padding: 0 56px 22px; border-bottom: 1px solid rgba(255,255,255,0.08); font-size: 12.5px; font-weight: 700; letter-spacing: 0.05em; color: #8a8a86; text-transform: uppercase; }
  .titleblock-big { padding: 44px 56px 0; }
  .intro-copy p { font-size: 16.5px; line-height: 1.75; color: #b7b7b3; margin-bottom: 16px; text-align: left; }
  .intro-copy p:last-child { margin-bottom: 0; }
  .side-credits { display: flex; flex-direction: column; }
  .side-credits .field { padding: 18px 0; border-top: 1px solid rgba(255,255,255,0.08); text-align: left; }
  .side-credits .field:last-child { border-bottom: 1px solid rgba(255,255,255,0.08); }
  .side-credits .field label { display: block; font-size: 11px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: #666; margin-bottom: 8px; }
  .side-credits .field span { display: block; font-size: 14.5px; font-weight: 600; line-height: 1.5; color: #e9e9e6; }
  .side-credits .field .role-list { list-style: disc; padding-left: 18px; margin-top: 2px; }
  .side-credits .field .role-list li { font-size: 14.5px; font-weight: 600; line-height: 1.5; color: #e9e9e6; margin-bottom: 4px; }
  .side-credits .field .role-list li:last-child { margin-bottom: 0; }
  .wide { padding: 0 56px; }
  .eyebrow-row { margin: 56px 0 20px; text-align: left; position: relative; z-index: 2; }
  .eyebrow-row .rule { height: 1px; background: rgba(255,255,255,0.08); margin-bottom: 28px; }
  .eyebrow-row .kicker { display: block; font-size: 12px; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: #0088ff; }
  .eyebrow-row .line { display: block; margin-top: 8px; font-size: 15px; color: #8a8a86; }
  .row3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; margin-bottom: 28px; align-items: stretch; }
  .row2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px; margin-bottom: 28px; align-items: stretch; }
  .row-single { margin-bottom: 28px; }
  .lb-item { position: relative; border-radius: 10px; overflow: hidden; cursor: zoom-in; background: #1e1e1e; box-shadow: 0 16px 34px -16px rgba(0,0,0,0.55); line-height: 0; }
  .lb-item img { width: 100%; height: auto; display: block; transition: transform .4s ease; }
  .lb-item:hover img { transform: scale(1.06); }
  .lb-item .zoom { position: absolute; top: 10px; right: 10px; width: 26px; height: 26px; border-radius: 50%; background: rgba(20,20,20,0.65); display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity .2s ease; font-size: 13px; color: #fff; }
  .lb-item:hover .zoom { opacity: 1; }
  .pull { max-width: 75%; margin: 60px auto 0; text-align: center; }
  .pull p { font-family: "Chivo", sans-serif; font-weight: 700; font-size: 25px; line-height: 1.4; color: #fff; }
  .pull p span { color: #00d4ff; }
  .hire { background: #1e1e1e; border-top: 1px solid rgba(255,255,255,0.08); border-bottom: 1px solid rgba(255,255,255,0.08); padding: 54px 56px; margin-top: 70px; }
  .hire-inner { display: flex; justify-content: space-between; align-items: center; gap: 40px; }
  .hire h3 { font-family: "Chivo", sans-serif; font-size: 24px; font-weight: 700; color: #fff; margin-bottom: 12px; }
  .skills { display: flex; flex-wrap: wrap; gap: 8px; }
  .skills span { background: rgba(0,136,255,0.12); border: 1px solid rgba(0,136,255,0.35); color: #6db8ff; padding: 6px 13px; border-radius: 999px; font-size: 12px; font-weight: 700; }
  .hire .cta-col { text-align: right; flex-shrink: 0; }
  .hire .cta { display: inline-block; background: #0088ff; color: #fff; font-size: 14px; font-weight: 800; padding: 15px 30px; border-radius: 999px; transition: background .2s ease, transform .4s ease; }
  a.cta:hover, button.cta:hover { background: #2e97ff; transform: scale(1.05); }
  .hire .cta-sub { display: block; margin-top: 12px; font-size: 12.5px; color: rgba(255,255,255,0.45); }
  .footer { display: flex; justify-content: space-between; align-items: center; margin-top: 88px; padding: 44px 56px; border-top: 1px solid rgba(255,255,255,0.08); position: relative; z-index: 2; }
  .footer span { font-size: 13px; color: rgba(255,255,255,0.4); }
  .footer .next { font-size: 13px; font-weight: 700; color: #00d4ff; transition: color .2s ease; }
  .footer .next:hover { color: #5be0ff; }
  .lightbox { position: fixed; inset: 0; background: rgba(10,10,10,0.94); display: none; align-items: center; justify-content: center; z-index: 50; flex-direction: column; }
  .lightbox.open { display: flex; }
  .lightbox .stage { position: relative; max-width: 84%; max-height: 74%; display: flex; align-items: center; justify-content: center; }
  .lightbox img { max-width: 100%; max-height: 100%; border-radius: 10px; box-shadow: 0 40px 80px -20px rgba(0,0,0,0.7); }
  .lightbox .close { position: absolute; top: 26px; right: 34px; width: 42px; height: 42px; border-radius: 50%; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.18); color: #fff; font-size: 20px; display: flex; align-items: center; justify-content: center; cursor: pointer; }
  .lightbox .close:hover { background: rgba(255,255,255,0.16); }
  .lightbox .arrow { position: absolute; top: 50%; transform: translateY(-50%); width: 52px; height: 52px; border-radius: 50%; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.18); color: #fff; font-size: 20px; display: flex; align-items: center; justify-content: center; cursor: pointer; }
  .lightbox .arrow:hover { background: rgba(0,136,255,0.55); }
  .lightbox .arrow.prev { left: 34px; }
  .lightbox .arrow.next { right: 34px; }
  .page-wipe { position: fixed; inset: 0; z-index: 9999; background: #0088ff; transform: translateY(0); pointer-events: none; }
  .page-wipe.animating { transition: transform .45s cubic-bezier(0.65, 0, 0.35, 1); }
  @media (prefers-reduced-motion: reduce) {
    .page-wipe { transition: none !important; transform: translateY(130%) !important; }
  }
  /* Experimental, mobile-only: thin 5px #161616 lines pinned to the very
     top and bottom edges, on top of the blue, in case it's enough to keep
     Safari's chrome tint sampling from reading pure blue during the wipe --
     unlike the earlier full-band attempt (tried and reverted, see CLAUDE.md),
     these are thin enough to be practically invisible if they don't help.
     Untestable in Chromium; needs confirmation on a real phone. */
  @media (max-width: 640px) {
    .page-wipe {
      background:
        linear-gradient(#161616, #161616) top / 100% 5px no-repeat,
        linear-gradient(#161616, #161616) bottom / 100% 5px no-repeat,
        #0088ff;
    }
  }
  /* Content slides 32px along with the opacity fade -- hidden state is
     displaced DOWN from its resting position, so the same toggle reads as
     "slides down as it fades out" on the way out and "slides up into place
     as it fades in" on the way in. .blob (the radial-gradient glows) and
     the ambient particle canvas (js/particles.js, prepended as .c's first
     child with no class -- hence :not(canvas) rather than a class name)
     both stay opacity-only, no slide: they're background decoration, not
     page content, and should hold still while everything else moves. The
     per-element stagger delay (js/transitions.js's fadeReveal/fadeCover)
     is applied via inline transition-delay, not here. */
  .c > *:not(.footer):not(.lightbox):not(.nav):not(canvas) { transition: opacity .6s cubic-bezier(0.22, 1, 0.36, 1), transform .6s cubic-bezier(0.22, 1, 0.36, 1); }
  .c > canvas, .blob { transition: opacity .6s ease; }
  html[data-pw-mode="fade"] .c > *:not(.footer):not(.lightbox):not(.nav):not(canvas):not(:has(.reveal-piece)) { opacity: 0; transform: translateY(32px); }
  html[data-pw-mode="fade"] .c > canvas { opacity: 0; }
  html[data-pw-mode="fade"] .blob { opacity: 0; }
  html[data-pw-mode="fade"][data-pw-revealed="1"] .c > *:not(.footer):not(.lightbox):not(.nav):not(canvas):not(:has(.reveal-piece)) { opacity: 1; transform: translateY(0); }
  html[data-pw-mode="fade"][data-pw-revealed="1"] .c > canvas { opacity: 1; }
  html[data-pw-mode="fade"][data-pw-revealed="1"] .blob { opacity: 0.22; }
  /* A .c > * direct child that :has() a .reveal-piece inside it opts out of
     the blanket per-block fade above entirely (it renders as a plain,
     always-visible wrapper) and instead each .reveal-piece within it fades/
     slides independently -- e.g. About's h1 building in before its body
     copy below, rather than the two fusing into one animated block. The
     nested stagger delay between pieces (anchored to the parent's own slot
     in the top-level sequence) is computed in js/transitions.js's
     fadeReveal()/fadeCover(), same technique as .masonry's individual
     .imgbox thumbnails elsewhere on this page. */
  .reveal-piece { transition: opacity .6s cubic-bezier(0.22, 1, 0.36, 1), transform .6s cubic-bezier(0.22, 1, 0.36, 1); }
  html[data-pw-mode="fade"] .reveal-piece { opacity: 0; transform: translateY(32px); }
  html[data-pw-mode="fade"][data-pw-revealed="1"] .reveal-piece { opacity: 1; transform: translateY(0); }
  @media (prefers-reduced-motion: reduce) {
    html[data-pw-mode="fade"] .c > *:not(.footer):not(.lightbox):not(.nav):not(canvas) { transition: none !important; opacity: 1 !important; transform: none !important; }
    html[data-pw-mode="fade"] .c > canvas { transition: none !important; opacity: 1 !important; }
    html[data-pw-mode="fade"] .blob { transition: none !important; opacity: 0.22 !important; }
    html[data-pw-mode="fade"] .reveal-piece { transition: none !important; opacity: 1 !important; transform: none !important; }
  }

  /* ===== Responsive ===== */
  @media (max-width: 900px) {
    .nav { padding: 26px 32px; }
    .wide { padding: 0 32px; }
    .metarow { padding: 0 32px 22px; }
    .titleblock-big { padding: 36px 32px 0; }
    .c .intro-split { padding: 32px 32px 48px; gap: 40px; }
    .c .hero { margin: 0 32px; margin-top: 32px; }
    .about-hero, .skills-section-row, .skills-section { padding-left: 32px; padding-right: 32px; gap: 40px; }
    .page-pad { padding-left: 32px; padding-right: 32px; }
    .hire { padding: 40px 32px; }
    .footer { padding: 36px 32px; }
  }

  @media (max-width: 640px) {
    body, .c { overflow-x: hidden; }
    .nav { padding: 20px; flex-wrap: wrap; row-gap: 10px; }
    .nav .links { gap: 16px; font-size: 12px; }
    .wide { padding: 0 20px; }
    .metarow { padding: 0 20px 18px; margin-top: 24px; font-size: 11px; }
    .metarow .cats { flex-wrap: wrap; row-gap: 6px; }
    .titleblock-big { padding: 24px 20px 0; }
    .c .titleblock-big h1, .contact-hero h1 { font-size: 34px !important; line-height: 1.14 !important; }
    .c .hero { margin: 0 20px; margin-top: 20px; border-radius: 12px !important; }
    .c .hero .play { width: 56px; height: 56px; }
    .c .hero .play:before { border-width: 9px 0 9px 15px; }
    .c .hero .vidtag { font-size: 10.5px; padding: 5px 11px; bottom: 12px; left: 12px; }
    .c .intro-split { grid-template-columns: 1fr !important; padding: 24px 20px 36px; gap: 28px; }
    .intro-copy p { font-size: 15px; }
    .eyebrow-row { margin: 32px 0 14px; }
    .row4, .row3, .row2, .c .row-wide-narrow, .c .row-narrow-wide, .c .row-wide-stack, .c .row-stack-wide {
      grid-template-columns: 1fr !important; gap: 14px; margin-bottom: 14px;
    }
    .row-single.quarter .lb-item { width: 60% !important; }
    .badge-row img { max-width: 100%; }
    .pull { max-width: 100%; padding: 0 20px; margin-top: 40px; }
    .pull p { font-size: 19px; }
    .hire { padding: 32px 20px; margin-top: 44px; }
    .hire-inner { flex-direction: column; align-items: flex-start; gap: 22px; }
    .hire .cta-col { text-align: left; }
    .footer { padding: 28px 20px; margin-top: 48px; flex-direction: column; align-items: flex-start; gap: 16px; }
    .lightbox .stage { max-width: 92%; max-height: 62%; }
    .lightbox .arrow { width: 42px; height: 42px; font-size: 16px; }
    .lightbox .arrow.prev { left: 10px; }
    .lightbox .arrow.next { right: 10px; }
    .lightbox .close { top: 14px; right: 14px; width: 36px; height: 36px; }

    /* contact.html */
    .page-pad { padding-left: 20px !important; padding-right: 20px !important; }
    .contact-hero { padding-top: 36px !important; }
    .contact-direct { flex-wrap: wrap; gap: 16px !important; margin-top: 24px !important; }
    .contact-form { margin: 36px 0 0 !important; padding: 22px !important; }
    .contact-form .field-row { grid-template-columns: 1fr !important; }
  }

  /* about.html goes single-column at a wider breakpoint than the rest of
     the site (780px vs. 640px elsewhere): its .about-hero/.skills-section*
     grids use a 2fr/3fr split that stays 2-column all the way down to
     640px, and at "middle-ground" widths in that range there wasn't
     enough room left in the 3fr column for the 3-column skills list (and
     the Download Résumé + LinkedIn button row) to fit without either
     wrapping or throwing off alignment against their own titles/rule
     lines above -- collapsing to a single column sooner sidesteps that
     squeeze entirely instead of trying to make it fit. */
  @media (max-width: 780px) {
    .about-hero { grid-template-columns: 1fr !important; padding: 24px 20px 0 !important; gap: 28px !important; }
    .about-copy h1 { font-size: 34px !important; line-height: 1.14 !important; margin-bottom: 20px !important; }
    .about-photo { max-width: 240px; }
    .skills-section-row, .skills-section { grid-template-columns: 1fr !important; padding: 0 20px !important; gap: 10px !important; }
    .skills-section-row .rule, .skills-section-row .kicker { grid-column: 1 !important; }
    .skills-section-row.first { margin-top: 36px !important; }
    .skills-columns { grid-column: 1 !important; column-count: 2 !important; }
  }
