/* =========================================================================
   Rossi Grimes portfolio
   1. Tokens
   2. Reset & base
   3. Background layers (wash + dot grid)
   4. Type primitives
   5. Components (buttons, links, placeholder slot)
   6. Nav
   7. Hero
   8. Motion
   9. Responsive
   ========================================================================= */

/* 1. Tokens ------------------------------------------------------------- */
:root {
  --paper:  #F7F5F2;
  --ink:    #0B0B0C;
  --muted:  #6B7075;
  --line:   #E2DED8;
  --ember:  #C2410C;
  --amber:  #E8873F;

  --slot-fill: #EAE6E0;
  --slot-line: #D5CFC6;

  --display: 'Source Serif 4', Georgia, 'Times New Roman', serif;
  --serif:   'Source Serif 4', Georgia, 'Times New Roman', serif;
  --mono:  'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

  --container: 1200px;
  --nav-h: 56px;
  --nav-bg: #FFFFFF;
  --wash-h: clamp(360px, 52vh, 560px);
  --hero-void: clamp(200px, 32vh, 320px);
  /* The one value that sets the left edge for every band on the page. */
  --pad: clamp(16px, 2.5vw, 32px);

  --r-sm: 4px;
  --r-md: 6px;
  --r-pill: 999px;

  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* 2. Reset & base ------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  position: relative;
  min-height: 100%;
  background-color: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; }

:focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 11px;
  padding: 10px 16px;
}
.skip:focus { left: 12px; top: 12px; }

.wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  /* Transparent rules stand in for the frame borders below, so the nav logo
     lands on the same line as the headline. */
  border-inline: 1px solid transparent;
}

/* The only rule on the page that sets a left edge. */
.band { padding-inline: var(--pad); }

/* 3. Background layers -------------------------------------------------- */
/* The wash is bounded to the container width and starts below the nav, so the
   bloom is contained rather than full-bleed. The dot grid is drawn over it, so
   the paper texture reads as continuous through the orange. */
.wash {
  position: absolute;
  top: var(--nav-h);
  left: 0;
  right: 0;
  margin-inline: auto;
  width: 100%;
  max-width: var(--container);
  height: var(--wash-h);
  z-index: 0;
  pointer-events: none;
  background:
    /* saturated core, top centre */
    radial-gradient(44% 58% at 50% -2%,
      rgba(194, 65, 12, .62)  0%,
      rgba(194, 65, 12, .40) 26%,
      rgba(210, 95, 30, .20) 48%,
      rgba(232, 135, 63, .06) 72%,
      rgba(232, 135, 63, 0)  90%),
    /* the bloom spreading off it */
    radial-gradient(80% 70% at 50% -8%,
      rgba(232, 135, 63, .44)  0%,
      rgba(232, 135, 63, .20) 40%,
      rgba(232, 135, 63, .05) 68%,
      rgba(232, 135, 63, 0)   88%),
    /* warmth carried out to the container edges */
    radial-gradient(128% 84% at 50% -14%,
      rgba(232, 135, 63, .16)  0%,
      rgba(232, 135, 63, 0)   72%);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 24%, rgba(0, 0, 0, 0) 100%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 24%, rgba(0, 0, 0, 0) 100%);
}

.dots {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image: radial-gradient(circle at 1px 1px,
    rgba(11, 11, 12, .085) 1px, rgba(11, 11, 12, 0) 1px);
  background-size: 22px 22px;
}

main, .nav { position: relative; z-index: 2; }

/* 4. Type primitives ---------------------------------------------------- */
/* One face, one weight, top to bottom. Heading levels differ by size only. */
h2, h3, h4 {
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.16;
  margin: 0;
}

p { margin: 0; }

/* 5. Components --------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: var(--r-pill);
  border: 1px solid transparent;
  padding: 11px 20px 10px;
  transition: background-color .22s var(--ease), color .22s var(--ease),
              border-color .22s var(--ease);
}

.btn-dark {
  background: var(--ink);
  color: var(--paper);
}
.btn-dark:hover { background: var(--ember); }

/* Hero CTA. The one place on the page that carries a gradient and a shadow
   rather than a hairline, because it is the only thing asking to be pressed. */
.btn-hero {
  gap: 10px;
  padding: 10px 9px 10px 20px;
  color: #FFF;
  background-image: linear-gradient(180deg, #3C3C41 0%, #232327 52%, #141417 100%);
  border-color: #08080A;
  box-shadow:
    0 1px 1px rgba(11, 11, 12, .18),
    0 7px 18px -7px rgba(11, 11, 12, .48),
    inset 0 1px 0 rgba(255, 255, 255, .10);
  transition: transform .18s var(--ease), box-shadow .18s var(--ease),
              filter .18s var(--ease);
}

.btn-hero:hover {
  transform: translateY(-1px);
  filter: brightness(1.12);
  box-shadow:
    0 2px 3px rgba(11, 11, 12, .16),
    0 14px 26px -8px rgba(11, 11, 12, .52),
    inset 0 1px 0 rgba(255, 255, 255, .14);
}

.btn-hero:active { transform: translateY(0); }

.btn-chev {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .15);
}

.link {
  font-family: var(--mono);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 1px solid var(--line);
  transition: color .22s var(--ease), border-color .22s var(--ease);
}
.link:hover { color: var(--ember); border-bottom-color: var(--ember); }

/* Placeholder slot.
   Sizing comes from the parent and --ar only, never from this styling, so a
   slot can be swapped for <img class="shot"> with no layout change. */
.slot,
.shot {
  width: 100%;
  aspect-ratio: var(--ar, 1);
  border-radius: var(--r-md);
}

.slot {
  display: grid;
  place-items: center;
  padding: 16px;
  background: var(--slot-fill);
  border: 1px dashed var(--slot-line);
}

.shot {
  height: auto;
  object-fit: cover;
  object-position: center;
}

.slot-label {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
  line-height: 1.7;
}

/* 6. Nav ---------------------------------------------------------------- */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 50;
  min-height: var(--nav-h);
  display: flex;
  align-items: center;
  background: var(--nav-bg);
  border-bottom: 1px solid var(--line);
}

.nav-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  min-height: var(--nav-h);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--ink);
  justify-self: start;
}

.mark { border-radius: 7px; flex: none; }

.nav-links {
  display: flex;
  align-items: center;
  gap: 4px;
  justify-self: center;
}

/* Squared off, unlike the pill buttons in the page body. */
.nav-cta {
  justify-self: end;
  border-radius: var(--r-sm);
}

.nav-links a {
  font-family: var(--mono);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  padding: 7px 12px;
  border-radius: var(--r-pill);
  transition: color .2s var(--ease), background-color .2s var(--ease);
}
.nav-links a:hover {
  color: var(--ink);
  background: rgba(11, 11, 12, .05);
}

/* 7. Hero --------------------------------------------------------------- */
/* Bounded container. The wash sits inside these side rules, not full-bleed,
   and they run the length of the page as the layout's spine. */
.frame {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  border-inline: 1px solid var(--line);
}

/* The top of the hero is deliberately empty: gradient only, no content. */
.hero {
  padding-top: calc(var(--nav-h) + var(--hero-void));
  padding-bottom: clamp(20px, 3vh, 32px);
}

/* One row, so the portrait's top edge sits on the headline's top edge. */
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 760px) minmax(0, 1fr);
  column-gap: clamp(24px, 3vw, 40px);
  /* Bottom-aligned, so the portrait finishes level with the button and takes
     whatever extra height it needs off the top. */
  align-items: end;
}

.hero-portrait {
  justify-self: end;
  width: clamp(180px, 18vw, 240px);
}

.hero-shot {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--ar, 3 / 4);
  object-fit: contain;
  object-position: bottom;
}

.hero-title {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.8rem, 3.2vw, 2.6rem);
  text-wrap: balance;
  line-height: 1.16;
  letter-spacing: 0;
}


.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px 22px;
  margin-top: clamp(28px, 4vh, 40px);
}

/* 7a2. Credit strip ------------------------------------------------------ */
.credit {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding-block: 20px;
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 17px;
  line-height: 1.6;
  color: var(--muted);
}

/* The next section draws its own top rule; without this the two hairlines
   would stack into one 2px line. */
.credit + .section { border-top: 0; }

/* 7b. Sections ---------------------------------------------------------- */
.section {
  border-top: 1px solid var(--line);
  padding-block: clamp(64px, 10vh, 120px);
  scroll-margin-top: var(--nav-h);
}

.eyebrow {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ember);
}

.section-title {
  font-size: clamp(1.5rem, 2.5vw, 2rem);
  margin-top: 14px;
}

.lede {
  font-size: clamp(16px, 1.35vw, 18px);
  line-height: 1.6;
  color: var(--muted);
  max-width: 52ch;
  margin-top: 16px;
}

.label {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.caption {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  line-height: 1.8;
  color: var(--muted);
  margin-top: 14px;
  max-width: 60ch;
}

/* 7c. Process strip ----------------------------------------------------- */
.steps {
  --steps-gap: clamp(32px, 4vw, 56px);
  list-style: none;
  margin: clamp(40px, 6vh, 64px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--steps-gap);
}

.step-media { position: relative; }

/* Chevron between panels, drawn in the gap so it costs no layout. */
.step:not(:last-child) .step-media::after {
  --arrow-t: translate(50%, -50%) rotate(45deg);
  content: '';
  position: absolute;
  top: 50%;
  right: calc(var(--steps-gap) / -2);
  width: 9px;
  height: 9px;
  border-top: 1px solid var(--muted);
  border-right: 1px solid var(--muted);
  transform: var(--arrow-t) scale(.55);
  opacity: 0;
}

.step-label {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink);
  margin-top: 14px;
}

.step-note {
  font-size: 15px;
  line-height: 1.6;
  color: var(--muted);
  margin-top: 8px;
  max-width: 34ch;
}

/* Panels rise in sequence, then the arrows arrive. Opacity and transform
   only, so each panel stays on its own compositor layer. */
.steps .step {
  opacity: 0;
  transform: translateY(16px);
}

.js-anim .steps .step {
  transition: opacity .55s var(--ease), transform .55s var(--ease);
}
.js-anim .steps .step:nth-child(2) { transition-delay: .12s; }
.js-anim .steps .step:nth-child(3) { transition-delay: .24s; }

.js-anim .step-media::after {
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.js-anim .steps .step:nth-child(1) .step-media::after { transition-delay: .82s; }
.js-anim .steps .step:nth-child(2) .step-media::after { transition-delay: .94s; }

.steps.is-in .step {
  opacity: 1;
  transform: none;
}
.steps.is-in .step-media::after {
  opacity: 1;
  transform: var(--arrow-t) scale(1);
}

/* Without JS nothing stays hidden. */
html:not(.js) .steps .step { opacity: 1; transform: none; }
html:not(.js) .step-media::after { opacity: 1; transform: var(--arrow-t) scale(1); }

.steps .video video,
.steps video {
  width: 100%;
  height: auto;
  aspect-ratio: 9 / 16;
  object-fit: cover;
  object-position: center;
  border-radius: var(--r-md);
}

/* 7d. Gallery ----------------------------------------------------------- */
/* Three fixed rows of three. Within a row each item grows in proportion to
   its own aspect ratio from a zero basis, so the widths land at r / sum(r)
   of the space and every height in the row comes out identical. --r is the
   image's measured ratio, set on the item. */
.gallery {
  display: grid;
  gap: 16px;
  margin-top: clamp(28px, 4vh, 40px);
}

.gallery-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: nowrap;
  gap: 16px;
}

.gallery-row > li {
  flex-grow: var(--r);
  flex-basis: 0;
  min-width: 0;
}

.tile {
  display: block;
  width: 100%;
  aspect-ratio: var(--r);
  padding: 0;
  border: 0;
  background: var(--slot-fill);
  border-radius: var(--r-md);
  overflow: hidden;
  cursor: zoom-in;
  transition: transform .25s var(--ease);
}
.tile:hover { transform: scale(1.02); }

.tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.tile-caption {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 10px;
}

/* 7e. Web builds -------------------------------------------------------- */
.builds {
  list-style: none;
  padding: 0;
  margin: clamp(28px, 4vh, 40px) 0 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(20px, 2.4vw, 28px);
}

.browser {
  display: block;
  text-decoration: none;
  color: inherit;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: border-color .22s var(--ease);
}
.browser[href]:hover { border-color: var(--ink); }

.browser-bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  background: #FFF;
  border-bottom: 1px solid var(--line);
}

.browser-dots {
  justify-self: start;
  display: inline-flex;
  gap: 5px;
}
.browser-dots i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #D4CEC6;
}

.browser-url {
  justify-self: center;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .08em;
  color: var(--muted);
}

/* Cover anchored to the top, so a taller capture would keep its header.
   These four are already the card's own ratio, so nothing is cropped. */
.build-shot {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--ar);
  object-fit: cover;
  object-position: top;
  background: var(--slot-fill);
}

.builds .caption { margin-top: 10px; }

/* 7f. Video ------------------------------------------------------------- */
/* Two rows: one full-width clip, then a pair. Within a row each item grows
   in proportion to its own ratio from a zero basis, so the row fills the
   width exactly and the heights match. Each box carries its own ratio, so
   cover crops nothing. */
.videos {
  display: grid;
  gap: 16px;
  margin-top: clamp(28px, 4vh, 40px);
}

.video-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: nowrap;
  gap: 16px;
}

.video-row > li {
  flex-grow: var(--r);
  flex-basis: 0;
  min-width: 0;
}

.vid-box {
  position: relative;
  width: 100%;
  aspect-ratio: var(--r);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--ink);
}

.vid-box video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.videos .caption { margin-top: 10px; }

/* Hidden unless the viewer has asked for less motion, in which case nothing
   autoplays and this is the way to start a clip. */
.vid-play {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 46px;
  height: 46px;
  padding: 0 0 0 2px;
  display: none;
  place-items: center;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 50%;
  cursor: pointer;
  transition: background-color .22s var(--ease), color .22s var(--ease);
}
.vid-play:hover { background: var(--ember); color: var(--paper); }
.vid-play[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .vid-play:not([hidden]) { display: grid; }
}

/* The process strip's own looping panel. */
.video { position: relative; }

.video-play {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 64px;
  height: 64px;
  padding: 0 0 0 3px;
  display: grid;
  place-items: center;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 50%;
}

/* Only live once script.js has upgraded it to a real control. */
button.video-play {
  cursor: pointer;
  transition: background-color .22s var(--ease), color .22s var(--ease);
}
button.video-play:hover {
  background: var(--ember);
  color: var(--paper);
}

/* 7f2. Video section spacing ------------------------------------------- */
/* The clips carry their own height, so this section opens tighter than the
   rest. */
#motion { padding-top: clamp(36px, 5vh, 60px); }

/* 7g. Services ---------------------------------------------------------- */
/* Four panels sharing edges. The container draws the top and left rules and
   each cell draws its own right and bottom, so nothing doubles up and the dot
   grid still shows through behind them. */
.services {
  list-style: none;
  margin: clamp(40px, 6vh, 64px) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
}

.services > li {
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: clamp(28px, 3.4vw, 48px);
}

.svc-icon {
  display: block;
  width: 64px;
  height: 64px;
  object-fit: contain;
}

.services h3 {
  font-size: clamp(1.4rem, 2.2vw, 1.75rem);
  margin-top: clamp(32px, 4vw, 52px);
}

.services p {
  font-size: 17px;
  line-height: 1.68;
  color: var(--ink);
  margin-top: 12px;
  max-width: 45ch;
}

/* 7h. About ------------------------------------------------------------- */
.about-body { margin-top: clamp(32px, 5vh, 48px); }

.about-body p {
  font-size: 17px;
  line-height: 1.75;
  max-width: 58ch;
}
.about-body p + p { margin-top: 1.2em; }

/* 7i. Contact & footer -------------------------------------------------- */
.contact-body { margin-top: clamp(32px, 5vh, 48px); }

.contact-email {
  display: inline-block;
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.15;
  font-size: clamp(1.5rem, 3.4vw, 2.25rem);
  color: var(--ink);
  text-decoration: none;
  word-break: break-word;
  transition: color .22s var(--ease);
}
.contact-email:hover { color: var(--ember); }

.contact-links {
  list-style: none;
  margin: clamp(24px, 4vh, 36px) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 22px;
}

.footer {
  border-top: 1px solid var(--line);
  padding-block: 28px clamp(40px, 6vh, 64px);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 24px;
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}

/* 7j. Lightbox ---------------------------------------------------------- */
.lb {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: clamp(56px, 8vw, 88px) clamp(16px, 5vw, 72px);
  background: rgba(11, 11, 12, .93);
}
.lb[hidden] { display: none; }

.lb-stage {
  display: grid;
  place-items: center;
  max-width: min(92vw, 1100px);
  max-height: 78vh;
}

/* Uncropped here, whatever shape the file is. */
.lb-stage img {
  width: auto;
  height: auto;
  max-width: min(92vw, 1100px);
  max-height: 78vh;
  object-fit: contain;
  border-radius: var(--r-md);
}

.lb-count {
  position: absolute;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  color: rgba(247, 245, 242, .6);
}

.lb-btn {
  position: absolute;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  padding: 0;
  color: var(--paper);
  background: rgba(247, 245, 242, .08);
  border: 1px solid rgba(247, 245, 242, .22);
  border-radius: 50%;
  cursor: pointer;
  transition: background-color .22s var(--ease);
}
.lb-btn:hover { background: rgba(247, 245, 242, .2); }
.lb-btn:focus-visible { outline-color: var(--paper); }

.lb-close { top: 16px; right: 16px; }
.lb-prev  { top: 50%; left: 16px;  transform: translateY(-50%); }
.lb-next  { top: 50%; right: 16px; transform: translateY(-50%); }

/* 8. Motion ------------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(14px);
}

.js-anim .reveal {
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}

.reveal.is-in {
  opacity: 1;
  transform: none;
}

.js-anim .reveal[data-delay="1"] { transition-delay: .07s; }
.js-anim .reveal[data-delay="2"] { transition-delay: .14s; }
.js-anim .reveal[data-delay="3"] { transition-delay: .21s; }

/* Without JS nothing stays hidden. */
html:not(.js) .reveal { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .reveal { opacity: 1 !important; transform: none !important; }
  .btn-hero:hover { transform: none; }
  .steps .step { opacity: 1 !important; transform: none !important; }
  .step-media::after { opacity: 1 !important; transform: var(--arrow-t) !important; }
}

/* 9. Responsive --------------------------------------------------------- */
@media (max-width: 900px) {
  .hero-grid {
    grid-template-columns: 1fr;
    row-gap: clamp(32px, 5vh, 48px);
  }
  .hero-portrait {
    justify-self: start;
    width: 320px;
  }
  /* Links are gone, so the bar is brand + CTA only. */
  .nav-links { display: none; }
  .nav-inner { grid-template-columns: auto 1fr; }


  .steps { grid-template-columns: 1fr; }
  .step:not(:last-child) .step-media::after {
    --arrow-t: translate(-50%, 50%) rotate(135deg);
    top: auto;
    right: auto;
    bottom: calc(var(--steps-gap) / -2);
    left: 50%;
  }
}

@media (max-width: 640px) {
  .hero { padding-bottom: 64px; }
  :root { --hero-void: clamp(140px, 22vh, 200px); }
  .hero-portrait { width: 260px; max-width: 100%; }
  .nav-inner { gap: 12px; }
  .btn { padding: 10px 16px 9px; font-size: 10px; }

  .services { grid-template-columns: 1fr; }

  /* One per row, each at its own natural ratio, so nothing is cropped. */
  .gallery { gap: 20px; }
  .gallery-row { display: block; }
  .gallery-row > li + li { margin-top: 20px; }

  .builds { grid-template-columns: 1fr; }

  .videos { gap: 20px; }
  .video-row { display: block; }
  .video-row > li + li { margin-top: 20px; }
  .lb-prev { left: 8px; }
  .lb-next { right: 8px; }
}
