/* ==========================================================================
   Rivside — rivside.com
   Single-page studio site. Dark throughout, cream on near-black, one accent.
   ========================================================================== */

@font-face {
  font-family: 'Archivo';
  src: url('/fonts/archivo-latin-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   Tokens
   --------------------------------------------------------------------------
   --accent is RIVSIDE red, #B3001B. Locked 2026-09-13. It is the only highlight
   colour in the system: the period in the wordmark, the nav status square, the
   marquee squares, link hovers, text selection, and the tint in the hero glow.
   Change it here and it changes everywhere at once.

   --on-accent is computed, not chosen: take the accent's relative luminance
   (0.2126R + 0.7152G + 0.0722B on linearised channels), contrast it against
   --bg, and if the ratio falls below 4.5:1 the foreground flips from ink-black
   to cream. RIVSIDE red scores 2.77:1 against #0a0a0a and 6.40:1 against
   #f4f2ec, so cream it is. Recompute both values if the accent ever changes.
   -------------------------------------------------------------------------- */
:root {
  --bg:        #0a0a0a;
  --ink:       #f4f2ec;
  --accent:    #b3001b;   /* RIVSIDE red */
  --on-accent: #f4f2ec;
  --row-hover: #101010;

  --hair:  rgba(244, 242, 236, .14);
  --pad-x: clamp(20px, 5vw, 64px);

  --ease-hover: cubic-bezier(.4, 0, .2, 1);
  --ease-enter: cubic-bezier(.16, 1, .32, 1);
  --ease-wipe:  cubic-bezier(.76, 0, .24, 1);
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */
* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: Archivo, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a {
  color: var(--ink);
  text-decoration: none;
  transition: color .35s var(--ease-hover);
}

::selection { background: var(--accent); color: var(--on-accent); }

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

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.hairline {
  height: 1px;
  margin: 0;
  border: 0;
  background: var(--hair);
}

.tnum { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }

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

/* --------------------------------------------------------------------------
   Keyframes
   -------------------------------------------------------------------------- */
@keyframes letterIn {
  from { transform: translateY(.55em) rotate(7deg); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
@keyframes marquee {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}
@keyframes wipeUp {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}
@keyframes wipeRight {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
@keyframes fadeMask {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* --------------------------------------------------------------------------
   Custom cursor — mounted by JS only when (pointer: fine)
   -------------------------------------------------------------------------- */
.cursor {
  position: fixed;
  top: 0; left: 0;
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border: 1px solid rgba(244, 242, 236, .55);
  border-radius: 50%;
  pointer-events: none;
  z-index: 80;
  opacity: 0;
  transform: scale(.28);
  mix-blend-mode: difference;
  transition: transform .3s var(--ease-enter), opacity .3s linear, border-color .3s linear;
  display: none;
}
.cursor.on { display: block; }
.cursor.hover {
  transform: scale(1);
  border-color: var(--accent);
}

/* --------------------------------------------------------------------------
   Nav — fades out rather than sitting as a solid bar. Static on scroll.
   -------------------------------------------------------------------------- */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 20px var(--pad-x);
  background: linear-gradient(#0a0a0a 55%, rgba(10, 10, 10, 0));
  backdrop-filter: blur(2px);
}
.nav-mark { display: flex; align-items: center; }
.nav-mark .wm { width: 118px; color: var(--ink); }

.nav-right {
  display: flex;
  align-items: center;
  gap: clamp(14px, 3vw, 40px);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: .14em;
  white-space: nowrap;
}

.clock {
  display: flex;
  align-items: center;
  gap: 8px;
  color: rgba(244, 242, 236, .55);
}
.clock-dot {
  width: 5px; height: 5px;
  background: var(--accent);
  display: block;
  flex: none;
}
.clock-time { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }

.btn-outline {
  flex: none;
  white-space: nowrap;
  border: 1px solid rgba(244, 242, 236, .28);
  padding: 11px clamp(14px, 1.6vw, 20px);
  letter-spacing: .14em;
  transition: background .4s var(--ease-hover), color .4s var(--ease-hover), border-color .4s ease;
}
.btn-outline:hover {
  background: var(--ink);
  color: var(--bg);
  border-color: var(--ink);
}

/* --------------------------------------------------------------------------
   1. Hero
   --------------------------------------------------------------------------
   min-height is tied to the headline's own scale, not a flat 100vh — a flat
   viewport height leaves a dead gap on short, wide windows.
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: min(100svh, calc(280px + 48vw));
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(88px, 18vh, 200px) var(--pad-x) clamp(36px, 6vh, 72px);
  overflow: hidden;
}

/* 14 stops interpolated in oklab with a front-loaded falloff. A 2-stop ramp
   bands severely across this distance; this is the shape that doesn't. */
.hero-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(125% 85% at 78% 10%,
    color-mix(in oklab, var(--accent) 10%,   #0a0a0a) 0%,
    color-mix(in oklab, var(--accent) 9.2%,  #0a0a0a) 8%,
    color-mix(in oklab, var(--accent) 8.3%,  #0a0a0a) 16%,
    color-mix(in oklab, var(--accent) 7.3%,  #0a0a0a) 24%,
    color-mix(in oklab, var(--accent) 6.3%,  #0a0a0a) 32%,
    color-mix(in oklab, var(--accent) 5.3%,  #0a0a0a) 40%,
    color-mix(in oklab, var(--accent) 4.4%,  #0a0a0a) 48%,
    color-mix(in oklab, var(--accent) 3.5%,  #0a0a0a) 56%,
    color-mix(in oklab, var(--accent) 2.7%,  #0a0a0a) 64%,
    color-mix(in oklab, var(--accent) 2%,    #0a0a0a) 72%,
    color-mix(in oklab, var(--accent) 1.3%,  #0a0a0a) 80%,
    color-mix(in oklab, var(--accent) 0.7%,  #0a0a0a) 88%,
    color-mix(in oklab, var(--accent) 0.3%,  #0a0a0a) 94%,
    color-mix(in oklab, var(--accent) 0%,    #0a0a0a) 100%);
}

/* The dither layer is what actually kills the residual banding. Not optional. */
.hero-dither {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: .055;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='d'><feTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/></filter><rect width='200' height='200' filter='url(%23d)'/></svg>");
}

.hero-h1 {
  position: relative;
  margin: 0;
  font-size: clamp(2.9rem, 10vw, 10.2rem);
  line-height: .88;
  letter-spacing: -.03em;
  text-transform: uppercase;
  font-weight: 900;
}
.hero-h1 .l1 { display: block; font-weight: 300; color: rgba(244, 242, 236, .88); }
.hero-h1 .l2 { display: block; font-weight: 900; }
.hero-h1 i {
  display: inline-block;
  font-style: normal;
  animation: letterIn .95s var(--ease-enter) both;
  animation-delay: var(--d, 0ms);
}
.hero-h1 .sp { width: .3em; animation: none; }
.hero-h1 .dot { color: var(--accent); }

.hero-sub {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(24px, 4vw, 64px);
  margin-top: clamp(32px, 5vh, 64px);
  animation: fadeMask 1s ease .95s both;
}
.hero-sub p {
  margin: 0;
  max-width: 38ch;
  font-size: clamp(15px, 1.35vw, 20px);
  font-weight: 300;
  line-height: 1.5;
  color: rgba(244, 242, 236, .66);
}

.btn-solid {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  background: var(--ink);
  color: var(--bg);
  padding: 18px 26px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .16em;
  transition: background .4s var(--ease-hover), color .4s ease;
}
.btn-solid:hover { background: var(--accent); color: var(--on-accent); }
.btn-rule { display: block; width: 22px; height: 1px; background: currentColor; }

/* --------------------------------------------------------------------------
   Hairline grid — the 1px gap on a hairline-coloured bed shows through as rules
   -------------------------------------------------------------------------- */
.grid-hair {
  display: grid;
  gap: 1px;
  background: var(--hair);
}
.cell { background: var(--bg); }

/* --------------------------------------------------------------------------
   2. Manifesto
   -------------------------------------------------------------------------- */
.manifesto { padding: clamp(90px, 16vh, 200px) var(--pad-x); }

.manifesto-h2 {
  margin: 0;
  max-width: 22ch;
  font-size: clamp(1.9rem, 5vw, 5.2rem);
  line-height: 1.02;
  letter-spacing: -.022em;
  font-weight: 300;
}
.manifesto-h2 span { display: block; }
.manifesto-h2 .b { font-weight: 700; }

.grid-manifesto {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  margin-top: clamp(56px, 9vh, 120px);
}
.grid-manifesto .cell { padding: clamp(28px, 3vw, 44px) clamp(24px, 2.4vw, 36px); }

.cell h3 {
  margin: 0 0 14px;
  font-size: clamp(20px, 1.9vw, 28px);
  font-weight: 800;
  letter-spacing: -.02em;
}
.cell p {
  margin: 0;
  font-size: 15px;
  font-weight: 300;
  line-height: 1.55;
  color: rgba(244, 242, 236, .6);
}

/* --------------------------------------------------------------------------
   3. Services — whole row is the mailto target
   -------------------------------------------------------------------------- */
.services { border-top: 1px solid var(--hair); }

.services-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  padding: clamp(60px, 9vh, 110px) var(--pad-x) clamp(24px, 4vh, 48px);
}
.services-head h2 {
  margin: 0;
  font-size: clamp(1.75rem, 3.8vw, 3.6rem);
  font-weight: 800;
  letter-spacing: -.025em;
  text-transform: uppercase;
  line-height: .9;
}
.services-head p {
  margin: 0;
  max-width: 30ch;
  font-size: 15px;
  font-weight: 300;
  line-height: 1.5;
  color: rgba(244, 242, 236, .55);
}

.row {
  display: grid;
  grid-template-columns: clamp(56px, 7vw, 120px) minmax(0, 1fr) minmax(0, 1.05fr) 40px;
  align-items: center;
  gap: clamp(12px, 2vw, 32px);
  border-top: 1px solid var(--hair);
  padding: clamp(24px, 3.4vh, 44px) var(--pad-x);
  transition: background .45s var(--ease-hover);
}
.row:hover { background: var(--row-hover); }
.row-last { border-bottom: 1px solid var(--hair); }

.row-i {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .14em;
  color: rgba(244, 242, 236, .45);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
}
.row-t {
  font-size: clamp(1.4rem, 2.9vw, 2.7rem);
  font-weight: 700;
  letter-spacing: -.022em;
  line-height: .95;
}
.row-d {
  font-size: 15px;
  font-weight: 300;
  line-height: 1.5;
  color: rgba(244, 242, 236, .6);
}
.row-r {
  justify-self: end;
  width: 26px; height: 1px;
  background: rgba(244, 242, 236, .5);
}

/* --------------------------------------------------------------------------
   4. Approach
   -------------------------------------------------------------------------- */
.approach { padding: clamp(80px, 13vh, 150px) 0 clamp(60px, 10vh, 120px); }

.marquee {
  overflow: hidden;
  padding: clamp(6px, 1vh, 14px) 0;
  border-top: 1px solid rgba(244, 242, 236, .1);
  border-bottom: 1px solid rgba(244, 242, 236, .1);
}
/* The block is duplicated exactly twice — that is what makes -50% seamless. */
.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 26s linear infinite;
}
.marquee-block {
  display: flex;
  align-items: center;
  gap: clamp(28px, 4vw, 64px);
  padding-right: clamp(28px, 4vw, 64px);
  font-size: clamp(1.5rem, 3.6vw, 3.4rem);
  letter-spacing: -.015em;
  text-transform: uppercase;
  white-space: nowrap;
}
.m-strong { font-weight: 700; color: rgba(244, 242, 236, .92); }
.m-soft   { font-weight: 300; color: rgba(244, 242, 236, .5); }
.m-sq {
  width: .5em; height: .5em;
  background: var(--accent);
  flex: none;
}

.approach-inner { padding: 0 var(--pad-x); }

.grid-approach {
  grid-template-columns: repeat(auto-fit, minmax(252px, 1fr));
  margin-top: clamp(48px, 8vh, 110px);
}
.cell-num { padding: clamp(28px, 3vw, 44px); }
.num {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .18em;
  color: rgba(244, 242, 236, .4);
}
.cell-num h3 {
  margin: clamp(40px, 7vh, 90px) 0 14px;
  font-size: clamp(22px, 2.1vw, 32px);
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: 1.05;
}

/* --------------------------------------------------------------------------
   5. About
   --------------------------------------------------------------------------
   The plate gradient is a fixed second colour — deliberately not derived from
   --accent. Changing the accent does not change this panel.
   -------------------------------------------------------------------------- */
.about {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  border-top: 1px solid var(--hair);
}

.plate {
  position: relative;
  min-height: min(84vh, 720px);
  background: linear-gradient(150deg, #0a0a0a 8%, #101a34 58%, #1b2c58 100%);
  overflow: hidden;
}
.plate-noise {
  position: absolute;
  inset: 0;
  opacity: .4;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/></filter><rect width='160' height='160' filter='url(%23g)'/></svg>");
}
.plate-mark {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  opacity: .8;
}
.plate-mark .wm { width: min(62%, 420px); }
.plate-cap {
  position: absolute;
  left: clamp(20px, 3vw, 36px);
  bottom: clamp(20px, 3vw, 36px);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .2em;
  color: rgba(244, 242, 236, .5);
}

.about-copy {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(24px, 3vh, 40px);
  padding: clamp(64px, 11vh, 140px) clamp(24px, 5vw, 80px);
}
.about-copy h2 {
  margin: 0;
  font-size: clamp(1.75rem, 3.4vw, 3.2rem);
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: .95;
  text-transform: uppercase;
}
.about-copy p {
  margin: 0;
  max-width: 46ch;
  font-size: clamp(16px, 1.35vw, 20px);
  font-weight: 300;
  line-height: 1.6;
  color: rgba(244, 242, 236, .72);
}

/* --------------------------------------------------------------------------
   6. Contact + footer
   -------------------------------------------------------------------------- */
.contact {
  border-top: 1px solid var(--hair);
  padding: clamp(90px, 17vh, 220px) var(--pad-x) clamp(40px, 6vh, 72px);
}
.contact-lead {
  margin: 0 0 clamp(28px, 5vh, 60px);
  max-width: 44ch;
  font-size: clamp(1rem, 1.5vw, 1.35rem);
  font-weight: 300;
  line-height: 1.5;
  color: rgba(244, 242, 236, .62);
}
.email {
  display: block;
  font-size: clamp(1.5rem, 5vw, 4.8rem);
  font-weight: 800;
  letter-spacing: -.028em;
  line-height: 1;
  word-break: break-word;
  transition: color .4s var(--ease-hover);
}
.email:hover { color: var(--accent); }

.footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-top: clamp(64px, 12vh, 150px);
  padding-top: 24px;
  border-top: 1px solid var(--hair);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: .14em;
  color: rgba(244, 242, 236, .45);
}

/* --------------------------------------------------------------------------
   Reveals — added by JS, never removed. Content is visible without JS, so the
   base state must stay unstyled: no opacity:0 here for script to undo.
   -------------------------------------------------------------------------- */
[data-played="up"]   { animation: wipeUp    .85s var(--ease-wipe) both; }
[data-played="wipe"] { animation: wipeRight .85s var(--ease-wipe) both; }

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

/* Below ~640px the four service columns cramp. Stack: index + title on one
   line, description beneath, rule dropped. */
@media (max-width: 640px) {
  .row {
    grid-template-columns: clamp(44px, 12vw, 56px) minmax(0, 1fr);
    row-gap: 10px;
  }
  .row-d { grid-column: 1 / -1; }
  .row-r { display: none; }

  .plate { min-height: min(56vh, 420px); }
  .grid-approach .cell-num h3 { margin-top: clamp(28px, 5vh, 48px); }
}

/* The clock and the button crowd each other on the narrowest phones. */
@media (max-width: 480px) {
  .clock { display: none; }
  .nav-mark .wm { width: 96px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .marquee-track { animation: none; }
  .hero-h1 i,
  .hero-sub,
  [data-played="up"],
  [data-played="wipe"] { animation: none; }
  .cursor { display: none !important; }
}
