/* ============================================================================
   Manraj Singh, portfolio. "Point cloud."
   js/field.js draws a field of particles behind the whole page: my name, a LiDAR
   room for NoStep, a month grid for Tartan, the Promptbox dog, a voice wave,
   Scotty, my portrait and "SAY HI". This file styles the text on top of it.
   ========================================================================= */

:root {
  --bg:   #0A0A0B;
  --bg-2: #141416;
  --fg:   #F2EEE8;   /* 17.6:1 on bg */
  --dim:  #9A948C;   /* 6.6:1 on bg */
  --hot:  #FF5A1F;   /* 6.4:1 on bg, measurements and the scan only */
  --line: rgb(242 238 232 / .14);

  --display: "Bricolage Grotesque", "Helvetica Neue", Arial, sans-serif;
  --body:    "IBM Plex Sans", "Helvetica Neue", Arial, sans-serif;
  --mono:    "IBM Plex Mono", ui-monospace, monospace;

  --ease: cubic-bezier(.22, 1, .36, 1);
  /* Never less than the notch on a landscape iPhone. */
  --pad: max(clamp(20px, 4.2vw, 64px), env(safe-area-inset-left, 0px), env(safe-area-inset-right, 0px));
  --nav: 76px;
  --safe-t: env(safe-area-inset-top, 0px);
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 24px;
}
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
html.locked, html.locked body { overflow: hidden; }
/* While the game runs, the hero is the playfield: clear the words off it. */
html.locked .hero-foot { animation: none; opacity: 0 !important; pointer-events: none; }
/* During the game, discovery toasts sit under the score, not on the paddle. */
html.locked .fx-toasts { bottom: auto; top: calc(max(16px, env(safe-area-inset-top, 0px)) + 64px); }
/* Focus moved by script onto a section: no ring around the whole section. */
[tabindex="-1"]:focus { outline: none; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 400 clamp(1rem, 1.1vw, 1.0625rem)/1.6 var(--body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; height: auto; }
p { margin: 0; }
a { color: inherit; }
button { font: inherit; color: inherit; }
h1, h2, h3 { margin: 0; font-weight: inherit; }
::selection { background: var(--hot); color: var(--bg); }
:focus-visible { outline: 2px solid var(--hot); outline-offset: 4px; }

.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: fixed;
  z-index: 60;
  left: 12px;
  top: -80px;
  padding: 12px 16px;
  background: var(--fg);
  color: var(--bg);
  font-weight: 600;
  text-decoration: none;
}
.skip:focus { top: 12px; }

.wrap {
  position: relative;
  width: 100%;
  max-width: calc(1360px + 2 * var(--pad));
  margin: 0 auto;
  padding: 0 var(--pad);
}

/* The field sits behind everything and never takes a click. */
.field {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
main { position: relative; z-index: 1; }

/* Links: an underline that draws in. */
.link {
  text-decoration: none;
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat;
  transition: background-size .3s var(--ease), color .2s var(--ease);
}
.link:hover, .link:focus-visible { background-size: 100% 1px; }
.link.strong { font-weight: 600; }

/* ============================================================================
   Navigation and cursor
   ========================================================================= */

.nav {
  position: fixed;
  z-index: 30;
  inset: 0 0 auto;
  height: calc(var(--nav) + var(--safe-t));
  padding: var(--safe-t) var(--pad) 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font: 500 15px/1 var(--body);
  mix-blend-mode: difference;
  color: #fff;
}
.nav-name {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font: 700 18px/1 var(--display);
  letter-spacing: -.035em;
  text-decoration: none;
}
.nav ul { display: flex; gap: clamp(16px, 2.4vw, 32px); margin: 0; padding: 0; list-style: none; }
.nav ul a { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px; }

/* The cursor: a hot dot that sheds the page's own dust as it moves (drawn by
   site.js). The system cursor hides only once that is running, and comes back
   over the screenshot viewer, which sits above every layer. */
.dust { position: fixed; inset: 0; z-index: 80; width: 100%; height: 100%; pointer-events: none; }
html.dust-on, html.dust-on * { cursor: none !important; }
html.dust-on:has(dialog[open]), html.dust-on:has(dialog[open]) * { cursor: revert !important; }
html:has(dialog[open]) .dust { display: none; }
@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) { .dust { display: none; } }

/* ============================================================================
   Hero
   ========================================================================= */

.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  grid-template-rows: 1fr auto;
  padding: calc(var(--nav) + var(--safe-t)) var(--pad) clamp(24px, 4vh, 44px);
}

/* With the field running, the name is drawn in particles; the heading stays
   for screen readers and search. Without it, the heading is the hero. */
.hero-name {
  align-self: center;
  justify-self: center;
  text-align: center;
  font: 800 clamp(4rem, 14vw, 13rem)/.86 var(--display);
  letter-spacing: -.06em;
}
.field-on .hero-name {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.hero-foot {
  position: relative;
  grid-row: 2;
  display: flex;
  justify-content: space-between;
  align-items: end;
  gap: 24px;
}
.hero-lines { display: grid; gap: 4px; font-size: clamp(.9375rem, 1.1vw, 1.0625rem); }
.hero-lines p:first-child { color: var(--dim); }
.hint {
  display: flex;
  align-items: center;
  gap: 18px;
  font: 400 12px/1 var(--mono);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--dim);
  white-space: nowrap;
}
.hint-touch { display: none; }
@media (hover: none) { .hint-fine { display: none; } .hint-touch { display: inline; } }
.hint-scroll { display: inline-flex; align-items: center; gap: 10px; }
.hint-scroll i {
  position: relative;
  width: 1px;
  height: 36px;
  overflow: hidden;
  background: var(--line);
}
.hint-scroll i::after {
  content: "";
  position: absolute;
  left: 0;
  top: -50%;
  width: 1px;
  height: 50%;
  background: var(--fg);
  animation: drip 1.8s var(--ease) infinite;
}
@keyframes drip { to { top: 100%; } }

/* The hero text arrives after the cloud has started to gather. */
@media (prefers-reduced-motion: no-preference) {
  .js .hero-foot { opacity: 0; transform: translateY(14px); animation: rise 1s var(--ease) 1.6s forwards; }
  .js .nav { opacity: 0; animation: fade .9s var(--ease) 1.2s forwards; }
}
@keyframes rise { to { opacity: 1; transform: none; } }
@keyframes fade { to { opacity: 1; } }

/* ============================================================================
   Sections
   ========================================================================= */

.section { position: relative; padding: clamp(110px, 16vh, 180px) 0; }

.index {
  margin-bottom: 22px;
  font: 400 13px/1.4 var(--mono);
  letter-spacing: .04em;
  color: var(--dim);
}
.h2 {
  font: 700 clamp(3.25rem, 8.6vw, 9rem)/.92 var(--display);
  letter-spacing: -.055em;
}
.h3 {
  font: 600 clamp(1.5rem, 2.2vw, 2rem)/1.08 var(--display);
  letter-spacing: -.035em;
}
.lead {
  font: 500 clamp(1.25rem, 2vw, 1.75rem)/1.35 var(--body);
  letter-spacing: -.015em;
}
.meta { font: 400 13px/1.45 var(--mono); color: var(--dim); }

/* Headings split into letters that rise through a mask; paragraphs lift in.
   Hidden only once the script that reveals them is running. */
.split .w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .12em; margin-bottom: -.12em; }
.split .ch { display: inline-block; }
@media (prefers-reduced-motion: no-preference) {
  .reveal-ready .split .ch { transform: translateY(108%); }
  .reveal-ready .split.is-in .ch { transform: none; transition: transform .9s var(--ease); transition-delay: calc(var(--i) * 24ms); }
  .reveal-ready .reveal { opacity: 0; transform: translateY(28px); }
  .reveal-ready .reveal.is-in { opacity: 1; transform: none; transition: opacity .9s var(--ease), transform .9s var(--ease); }
}

/* Below 1024px each shape gets an empty stage of its own instead of sitting
   behind the words. */
.stage { display: none; }
@media (max-width: 1023px) { .field-on .stage { display: block; height: 72svh; } }

/* Content column: the cloud's shape lives in the other half on desktop. */
.col { max-width: 44rem; display: grid; gap: 24px; }
.col > .h2 { margin-bottom: 8px; }

/* --- NoStep ------------------------------------------------------------------ */
.nostep .col p:not(.lead):not(.index) { color: var(--dim); max-width: 38rem; }

.demo {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
  margin: clamp(64px, 9vh, 104px) 0 0;
  padding: clamp(20px, 3vw, 36px);
  border: 1px solid var(--line);
  border-radius: 20px;
  background: rgb(20 20 22 / .82);
}
.demo-svg { display: block; width: 100%; height: auto; overflow: visible; }
.demo-mini { display: none; }
.demo svg path, .demo svg rect { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.demo svg text { font: 500 12px var(--mono); }
.d-wall [data-wall]  { stroke: var(--fg); stroke-width: 1.3; }
.d-wall [data-door]  { fill: rgb(242 238 232 / .06); stroke: var(--fg); stroke-width: 1.6; }
.d-wall [data-floor] { stroke: rgb(242 238 232 / .25); stroke-width: 1; }
.d-wall [data-card]  { stroke: var(--dim); stroke-width: 1; }
.d-dim path { stroke: var(--fg); stroke-width: 1; }
.d-dim text { fill: var(--fg); }
.d-rect rect, .demo-mini rect { stroke: var(--dim); stroke-width: 1; stroke-dasharray: 3 3; }
.d-rect path, .demo-mini path { fill: rgb(255 90 31 / .16); stroke: var(--hot); stroke-width: 1.6; }
.d-rect text, .demo-mini text { fill: var(--dim); font-size: 10px; }
.d-cam path { stroke: var(--dim); stroke-width: .8; stroke-dasharray: 2 4; }
.d-cam circle { fill: var(--hot); }

.demo-side { display: grid; gap: 20px; align-content: start; }
.readings { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 0; }
.reading { display: grid; gap: 8px; padding-top: 12px; border-top: 1px solid var(--fg); }
.reading dt { font: 400 12px/1.3 var(--mono); letter-spacing: .04em; text-transform: uppercase; color: var(--dim); }
.reading dd {
  margin: 0;
  font: 500 clamp(1.75rem, 3.4vw, 3.25rem)/1 var(--mono);
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
}
.reading-true { border-top-color: var(--hot); }
.reading-true dd { color: var(--hot); }
.slider-label { font: 400 12px/1 var(--mono); letter-spacing: .04em; text-transform: uppercase; color: var(--dim); }
.demo-note { color: var(--dim); font-size: .9375rem; }
/* From 1024px the cloud gets the right half of the screen to itself. */
@media (min-width: 1024px) {
  .nostep .wrap > *, .work .col, .project-split, .rows, .about-body { max-width: min(48vw, 700px); }
  .demo { grid-template-columns: minmax(0, 1fr); }
  .project-split { grid-template-columns: minmax(0, 1fr); }
  .rows .row { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .rows .row .link { justify-self: start; }
  .field-on .about-grid { grid-template-columns: minmax(0, 1fr); }
}
/* With the field running, the portrait is drawn in particles beside the text. */
.field-on .portrait { display: none; }

input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 44px;
  margin: -10px 0 0;
  background: transparent;
  cursor: ew-resize;
}
input[type="range"]::-webkit-slider-runnable-track { height: 2px; background: var(--fg); }
input[type="range"]::-moz-range-track { height: 2px; background: var(--fg); }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 24px;
  height: 24px;
  margin-top: -11px;
  border: 0;
  border-radius: 50%;
  background: var(--hot);
  box-shadow: 0 0 0 6px rgb(255 90 31 / .22);
}
input[type="range"]::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 50%;
  background: var(--hot);
  box-shadow: 0 0 0 6px rgb(255 90 31 / .22);
}

/* --- Builds ------------------------------------------------------------------ */
.builds .h2 { margin-bottom: clamp(56px, 8vh, 96px); }
.project-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 460px);
  gap: 24px 64px;
  align-items: end;
}
.project-name {
  font: 700 clamp(2.5rem, 5vw, 4.5rem)/1 var(--display);
  letter-spacing: -.05em;
}
.project-copy, .project-side { display: grid; gap: 16px; justify-items: start; }
.project-copy p, .project-side p { color: var(--dim); }

.shots { max-width: 1180px; margin: 44px auto 0; }
.shot-stage { perspective: 1400px; }
.shot-frame {
  position: relative;
  padding: clamp(6px, .9vw, 12px);
  border: 1px solid var(--line);
  border-radius: clamp(12px, 1.6vw, 22px);
  background: var(--bg-2);
  box-shadow: 0 40px 120px -40px rgb(0 0 0 / .9);
  transform-origin: 50% 100%;
}
.shot-clip { position: relative; overflow: hidden; border-radius: clamp(6px, .8vw, 12px); }
.shot-clip img { width: 100%; }
.shot-next { position: absolute; inset: 0; width: 100%; height: 100%; }
.shot-next[hidden] { display: none; }
@media (min-width: 768px) and (prefers-reduced-motion: no-preference) {
  .reveal-ready [data-tilt] .shot-frame { transform: rotateX(16deg) translateY(60px) scale(.94); opacity: .4; }
  .reveal-ready [data-tilt].is-in .shot-frame { transform: none; opacity: 1; transition: transform 1.2s var(--ease), opacity 1.2s var(--ease); }
}

.tabs {
  display: inline-grid;
  grid-auto-flow: column;
  gap: 4px;
  margin-top: 18px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgb(20 20 22 / .8);
}
.tabs button {
  min-height: 44px;
  padding: 0 20px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--dim);
  font-weight: 500;
  font-size: 15px;
  cursor: pointer;
  transition: background .25s var(--ease), color .25s var(--ease);
}
.tabs button:hover { color: var(--fg); }
.tabs button[aria-selected="true"] { background: var(--fg); color: var(--bg); }
.shots .tabs { display: flex; width: max-content; max-width: 100%; margin-inline: auto; }

.shot-caption {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 16px;
  margin-top: 14px;
  font: 400 12px/1.5 var(--mono);
  color: var(--dim);
}
.enlarge { display: none; align-items: center; min-height: 44px; color: var(--fg); font-family: var(--body); font-size: 14px; font-weight: 600; }

.project-split {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 80px);
  align-items: center;
  margin-top: clamp(96px, 14vh, 160px);
}
.shot-single { margin: 0; }

.rows { margin-top: clamp(96px, 14vh, 160px); border-top: 1px solid var(--line); }
.row {
  display: grid;
  grid-template-columns: minmax(0, 340px) minmax(0, 1fr) auto;
  gap: 16px 40px;
  align-items: baseline;
  padding: 36px 0;
  border-bottom: 1px solid var(--line);
  transition: padding .4s var(--ease);
}
.row p { color: var(--dim); max-width: 40rem; }
.row-name { font: 700 clamp(1.75rem, 3vw, 2.75rem)/1.05 var(--display); letter-spacing: -.045em; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .row:hover { padding-left: 16px; }
  .row:hover .row-name { color: var(--hot); }
}

/* The Soundalike radio: its dial turns the cloud into sand on a plate. */
.radio { grid-column: 1 / -1; display: grid; gap: 14px; max-width: 40rem; padding-top: 4px; }
.radio[hidden] { display: none; }
.radio-top { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.radio-freq { font: 500 clamp(1.5rem, 2.6vw, 2.25rem)/1 var(--mono); letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.radio-status { margin: 0; font: 400 13px/1.4 var(--mono); color: var(--dim); }
.radio.on-air .radio-freq, .radio.on-air .radio-status { color: var(--hot); }

/* The ball Scotty fetches at Work. */
.fetch-ball {
  position: fixed; left: 0; top: 0; z-index: 45;
  width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%;
  background: #fff; box-shadow: 0 0 12px 2px rgb(255 90 31 / .8);
  pointer-events: none; opacity: 0;
}

/* --- Work -------------------------------------------------------------------- */
.work .h2 { font-size: clamp(2.75rem, 6.4vw, 6.5rem); margin-bottom: 32px; }
.role { display: grid; gap: 10px; padding: 28px 0; border-top: 1px solid var(--line); }
.role-name { font: 700 clamp(1.75rem, 2.6vw, 2.5rem)/1.05 var(--display); letter-spacing: -.045em; }
.role p:not(.meta) { color: var(--dim); max-width: 40rem; }

/* --- About ------------------------------------------------------------------- */
.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
  gap: 48px clamp(40px, 6vw, 96px);
  align-items: start;
}
.portrait {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 18px;
  filter: grayscale(.2) contrast(1.04);
}
.about-body { display: grid; gap: 22px; max-width: 46rem; }
.paper { display: grid; gap: 10px; padding: 26px 0; border-block: 1px solid var(--line); }
.paper-title { font: 600 clamp(1.25rem, 1.9vw, 1.625rem)/1.2 var(--display); letter-spacing: -.025em; }
.paper-title a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; text-decoration-color: rgb(242 238 232 / .4); }
.paper-title a:hover { text-decoration-color: var(--hot); }
.paper > p:last-child { color: var(--dim); }
.facts { display: grid; gap: 18px; margin: 0; padding: 0; list-style: none; }
.facts li { display: grid; gap: 4px; }
.facts b { font-weight: 600; }
.facts span { color: var(--dim); }

/* --- Contact ------------------------------------------------------------------ */
.contact {
  position: relative;
  min-height: 100svh;
  display: grid;
  align-items: end;
  /* Clear of the Discoveries pill in the corner. */
  padding: 0 0 max(80px, calc(64px + env(safe-area-inset-bottom, 0px)));
}
.contact .wrap { display: grid; gap: 24px; }
.contact-copy { max-width: 36rem; font-size: clamp(1.0625rem, 1.4vw, 1.25rem); color: var(--dim); }
.contact-email {
  justify-self: start;
  max-width: 100%;
  font: 700 clamp(1.75rem, 5.6vw, 5.5rem)/1 var(--display);
  letter-spacing: -.055em;
  text-decoration: none;
  overflow-wrap: anywhere;
  transition: color .3s var(--ease);
}
.contact-email:hover, .contact-email:focus-visible { color: var(--hot); }
.contact-links { display: flex; flex-wrap: wrap; gap: 8px 32px; margin: 0; padding: 0; list-style: none; }
.contact-links a { display: inline-flex; align-items: center; min-height: 48px; font-weight: 600; }
.foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-top: clamp(32px, 6vh, 64px);
  padding-top: 18px;
  border-top: 1px solid var(--line);
  font: 400 13px/1 var(--mono);
  color: var(--dim);
}
.foot a { display: inline-flex; align-items: center; min-height: 44px; color: var(--fg); }

/* --- screenshot viewer --------------------------------------------------------- */
.viewer {
  width: 100vw;
  height: 100dvh;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--bg);
  color: var(--fg);
}
.viewer[open] { display: grid; grid-template-rows: auto minmax(0, 1fr); }
.viewer::backdrop { background: var(--bg); }
.viewer-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding: calc(8px + var(--safe-t)) 16px 8px 20px;
  font-weight: 600;
}
.viewer-close {
  min-width: 44px;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  font-weight: 600;
  cursor: pointer;
}
.viewer-body { overflow: auto; overscroll-behavior: contain; padding: 0 16px 16px; }
.viewer-body img { width: auto; max-width: none; height: 100%; }

/* ============================================================================
   Responsive
   ========================================================================= */

/* Below 1024px the shapes sit behind the words, dimmed: give the words a floor. */
@media (max-width: 1023px) {
  /* Text that the shapes can drift behind gets a dark halo. */
  .builds .wrap > .index, .builds .h2, .project-head, .shot-caption {
    text-shadow: 0 0 6px var(--bg), 0 0 16px var(--bg), 0 0 28px var(--bg);
  }
  .nostep .col, .work .col, .project-split .project-side, .rows, .about-body { padding: 24px var(--pad); margin: 0 calc(-1 * var(--pad)); background: linear-gradient(rgb(10 10 11 / 0), rgb(10 10 11 / .74) 10%, rgb(10 10 11 / .74) 90%, rgb(10 10 11 / 0)); }
}

@media (max-width: 1100px) {
  .demo { grid-template-columns: minmax(0, 1fr); }
  .project-split { grid-template-columns: minmax(0, 1fr); }
  .row { grid-template-columns: minmax(0, 260px) minmax(0, 1fr) auto; }
}

@media (max-width: 767px) {
  :root { --nav: 64px; }
  /* Room under the hint for the Discoveries pill fixed at the bottom right. */
  .hero-foot { flex-direction: column; align-items: start; padding-bottom: 56px; }
  .hint { gap: 14px; }
  .hint-scroll i { height: 24px; }

  /* On phones the shapes sit behind the words, dimmed; give the words a floor. */
  .col, .about-body, .contact .wrap > * { position: relative; }

  .demo { padding: 18px; border-radius: 16px; }
  .d-rect { display: none; }
  .demo-svg { overflow: hidden; }
  .demo-art { display: grid; grid-template-columns: minmax(0, 1fr) 76px; gap: 10px; align-items: center; }
  .demo-mini { display: block; width: 100%; height: auto; overflow: visible; }
  /* At phone width these labels shrink to 4px; the readings below carry them. */
  .d-dim text, .demo-mini text { display: none; }

  .project-head { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .shots .tabs { width: 100%; }
  .shots .tabs button { flex: 1; padding: 0 6px; font-size: 14px; }
  .enlarge { display: inline-flex; }
  .project-split .shot-single { order: 2; }
  .row { grid-template-columns: minmax(0, 1fr); gap: 12px; padding: 28px 0; }

  .about-grid { grid-template-columns: minmax(0, 1fr); }
  .portrait { width: 160px; }
  .contact { align-items: end; }
  .foot { flex-direction: column; align-items: start; }
}

/* ============================================================================
   Reduced motion: everything lands at once.
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-delay: 0s !important;
    transition-duration: .001ms !important;
    transition-delay: 0s !important;
  }
  .hint-scroll i::after { display: none; }
}

@media print {
  .field, .dust, .fetch-ball, .radio, .nav, .tabs, .enlarge, input[type="range"], .stage { display: none !important; }
  body { background: #fff; color: #000; }
  :root { --fg: #000; --dim: #444; }
  .reveal, .split .ch, [data-tilt] .shot-frame { opacity: 1 !important; transform: none !important; }
  .field-on .hero-name { position: static; width: auto; height: auto; overflow: visible; clip-path: none; white-space: normal; font-size: 40pt; }
  .hero, .contact { min-height: 0; }
}
