  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; min-width: 0; min-height: 100vh; color: #f2f2f0; font-family: "Plus Jakarta Sans", -apple-system, "Helvetica Neue", Arial, sans-serif; position: relative; overflow: hidden; }

  .blob-layer { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
  .blob { position: absolute; border-radius: 50%; opacity: 0.22; }
  .blob-anchor-bottom { transform: translateY(var(--flip-y, 0px)); will-change: transform; }
  /* Blobs live in .blob-layer, a direct child of body (not .c) so their glow
     reaches the true page edges on a very wide window instead of stopping at
     .c's 1440px column; .c's own background above is removed so the glow
     shows through the content column too, not just the margins beside it.
     .blob-layer is absolutely positioned with inset:0, so it exactly matches
     body's own box (same width/height, still scrolls with the page) -- its
     overflow:hidden clips each blob's radial-gradient bleed right at that
     true edge instead of letting it (invisibly) extend past it, which was
     adding extra scrollable width to body's overflow-x:auto and letting the
     page scroll further right than it should. */
  /* While a filter change is easing the footer into its new spot, .c's own
     height has already snapped to the new, shorter value -- so the footer
     briefly renders past .c's new bottom edge mid-ease. Lifting the clip
     just for that window stops it from getting cut off; it's restored once
     things settle. */
  /* .c is a flex item of body with no explicit min-width, so by default its
     automatic minimum width tracks its overflow value: overflow:hidden lets it
     shrink-to-fit narrower windows (min-width resolves to 0), but overflow:
     visible makes that resolve to its full 1440px instead -- which, without the
     min-width:0 above, briefly un-shrinks .c back to 1440px (pushing it off-
     center) for exactly the window .is-filtering is applied. min-width:0 makes
     the shrink-to-fit behavior permanent regardless of overflow. */
  .c.is-filtering { overflow: visible; }

  .nav { display: flex; align-items: center; justify-content: space-between; padding: 34px 56px; position: relative; z-index: 2; border-bottom: 1px solid rgba(255,255,255,0.08); }
  .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 .links { display: flex; 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 .4s 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 { padding: 34px 56px 60px; max-width: 900px; position: relative; z-index: 2; }
  .hero .eyebrow { display: block; margin-bottom: 14px; font-size: 12px; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: #0088ff; }
  .hero h1 { font-family: "Chivo", -apple-system, sans-serif; font-size: 58px; line-height: 1.08; font-weight: 900; letter-spacing: -0.02em; color: #fff; }
  .hero h1 .hl { color: #0088ff; }
  .hero p { margin-top: 22px; font-size: 17px; line-height: 1.6; color: #9a9a9a; max-width: 560px; }

  /* CSS multi-column (column-count) used to lay these out, but Safari has
     deep, long-standing bugs when a column-fragmented item contains a
     transform that changes (hover, drift, the filter FLIP slide) -- cards
     would flicker, render blank until hover, or even jump into a different
     column entirely. Three explicit flex columns sidestep that whole bug
     class (there's no column fragmentation happening at all), at the cost
     of the column split being fixed in the HTML (see .masonry-col) rather
     than auto-rebalanced -- it was hand-distributed to be close to even. */
  .masonry { display: flex; align-items: flex-start; gap: 22px; padding: 0 56px; position: relative; z-index: 2; }
  .masonry-col { display: flex; flex-direction: column; gap: 22px; flex: 1 1 0; min-width: 0; }
  /* .card itself is the item CSS multi-column fragments (break-inside:
     avoid) -- it stays a plain, untransformed box on purpose. Safari has a
     documented bug where a 3D transform on a column-fragmented item throws
     off where the next column starts, which is what was pushing the
     right-hand column down. All the animated stuff (drift, hover, the FLIP
     slide) lives on .card-visual instead, one level in, so it gets its own
     persistent GPU layer without .card itself ever being transformed. */
  .card { --dx: 0px; --dy: 0px; --s: 1; --lift: 0px; position: relative; opacity: var(--fo, 1); }
  .card:hover { z-index: 3; }
  .card-visual { display: block; background: #1e1e1e; border: 1px solid rgba(255,255,255,0.07); border-radius: 20px; overflow: hidden; box-shadow: 0 8px 24px -10px rgba(0,0,0,0.6); transform: translate3d(calc(var(--dx) + var(--flip-x, 0px)), calc(var(--dy) + var(--lift) + var(--flip-y, 0px)), 0) scale(calc(var(--s) * var(--fs, 1))); transition: box-shadow .28s ease, border-color .28s ease; will-change: transform; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
  .card:hover .card-visual { box-shadow: 0 24px 48px -14px rgba(0,136,255,0.35); border-color: rgba(0,212,255,0.35); }
  .card .imgbox { position: relative; overflow: hidden; }
  .card .imgbox img { width: 100%; height: 100%; display: block; object-fit: cover; transition: transform .4s ease; filter: saturate(0.94); transform: scale(1) translateZ(0); -webkit-backface-visibility: hidden; backface-visibility: hidden; }
  .card:hover img { transform: scale(1.06) translateZ(0); }
  .card .tags { position: absolute; top: 14px; left: 14px; display: flex; flex-wrap: wrap; gap: 6px; max-width: calc(100% - 28px); z-index: 2; }
  .card .tag { background: rgba(20,20,20,0.75); backdrop-filter: blur(6px); padding: 6px 12px; border-radius: 999px; font-size: 11px; font-weight: 700; letter-spacing: 0.02em; box-shadow: 0 4px 12px -4px rgba(0,0,0,0.4); }
  .tag.blue { color: #2e90ff; } .tag.cyan { color: #00d4ff; } .tag.violet { color: #8b7bff; } .tag.coral { color: #ff6b6b; } .tag.amber { color: #ffb648; } .tag.teal { color: #34d399; } .tag.pink { color: #f472b6; }
  .card .scrim { position: absolute; left: 0; right: 0; bottom: 0; padding: 46px 20px 20px; background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.85) 88%); opacity: 0; transform: translateY(8px) translateZ(0); transition: opacity .3s ease, transform .3s ease; -webkit-backface-visibility: hidden; backface-visibility: hidden; }
  .card:hover .scrim { opacity: 1; transform: translateY(0) translateZ(0); }
  .card .scrim h3 { color: #fff; font-size: 24px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.15; }
  .card.is-hidden { display: none; }

  .filters { display: flex; flex-wrap: wrap; gap: 10px; padding: 0 56px 34px; position: relative; z-index: 2; }
  .filter-btn { appearance: none; cursor: pointer; border: 1.5px solid rgba(255,255,255,0.14); background: #1e1e1e; color: #f2f2f0; padding: 9px 18px; border-radius: 999px; font-size: 13px; font-weight: 700; letter-spacing: 0.01em; font-family: inherit; transition: border-color .15s ease, background .15s ease, color .15s ease; }
  .filter-btn:hover { border-color: var(--fc, #f2f2f0); }
  .filter-btn.active { background: var(--fc, #0088ff); border-color: var(--fc, #0088ff); color: #0c0c0c; }

  /* A thin divider line, matching the .nav border-bottom above -- this
     used to be a scrolling blue marquee bar of category names; kept as
     the same .marquee element/class (still a FLIP trail element, see
     trailEls in homepage.js) so it still eases into place in sync with
     the footer during filter transitions, just styled as a line now. */
  .marquee { margin: 60px 56px 0; height: 1px; background: rgba(255,255,255,0.08); position: relative; z-index: 2; transform: translateY(var(--flip-y, 0px)); will-change: transform; }

  .footer { display: flex; justify-content: space-between; align-items: center; padding: 50px 56px; position: relative; z-index: 2; border-top: 1px solid rgba(255,255,255,0.08); transform: translateY(var(--flip-y, 0px)); will-change: transform; }
  .footer span { color: #f2f2f0; }
  .footer .cta { background: #0088ff; color: #ffffff; font-size: 13px; font-weight: 700; padding: 14px 26px; border-radius: 999px; transition: background .2s ease, transform .4s ease; }
  a.cta:hover, button.cta:hover { background: #2e97ff; transform: scale(1.05); }

  a.card { display: block; }
  .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(100%) !important; }
  }
  .c > *:not(.footer):not(.lightbox):not(.nav), .blob { transition: opacity .4s ease; }
  html[data-pw-mode="fade"] .c > *:not(.footer):not(.lightbox):not(.nav), html[data-pw-mode="fade"] .blob { opacity: 0; }
  html[data-pw-mode="fade"][data-pw-revealed="1"] .c > *:not(.footer):not(.lightbox):not(.nav) { opacity: 1; }
  html[data-pw-mode="fade"][data-pw-revealed="1"] .blob { opacity: 0.22; }
  @media (prefers-reduced-motion: reduce) {
    html[data-pw-mode="fade"] .c > *:not(.footer):not(.lightbox):not(.nav) { transition: none !important; opacity: 1 !important; }
    html[data-pw-mode="fade"] .blob { transition: none !important; opacity: 0.22 !important; }
  }
