/* Чёрно-белая страница. Весь цвет — в фото на первом экране и в работах заказчиков:
   на нейтральном фоне разница между тремя сайтами видна сразу. */
:root {
  --paper: #ffffff;
  --ink: #000000;
  --muted: #666666;
  --line: #dcdcdc;
  --hover: #f1f1f1;

  --display: "Unbounded", "Arial Black", "Segoe UI", sans-serif;
  --text: "Sofia Sans", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;

  --gutter: 16px;
  --section: 64px;
  --radius: 10px;
}

/* Шрифты Sofia Sans и Unbounded (лицензия OFL) скачаны с Google Fonts и лежат в папке fonts:
   так страница не обращается к чужим серверам. Диапазоны символов — как у Google. */
@font-face {
  font-family: "Sofia Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/sofia-sans-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: "Sofia Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("fonts/sofia-sans-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Unbounded";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/unbounded-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: "Unbounded";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("fonts/unbounded-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

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

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

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 1.125rem/1.5 var(--text);
  overflow-wrap: break-word;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

h1,
h2,
h3,
p,
figure {
  margin: 0;
}

h1,
h2,
h3 {
  font-family: var(--display);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

h2 {
  font-size: clamp(1.5rem, 6.2vw, 2.75rem);
}

h3 {
  font-size: clamp(1.25rem, 4.4vw, 1.75rem);
}

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

.wrap {
  max-width: 1344px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.link {
  color: inherit;
  font-weight: 600;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 2px;
}

.link:hover {
  color: var(--muted);
}

/* Кнопка */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 58px;
  padding: 0 26px;
  border-radius: var(--radius);
  background: var(--ink);
  color: #fff;
  font: 600 1.125rem/1 var(--text);
  text-decoration: none;
}

.btn svg {
  flex: none;
  width: 22px;
  height: 22px;
  fill: currentColor;
}

.btn--light {
  background: #fff;
  color: #000;
}

.btn--light:hover {
  background: #e4e4e4;
}

/* Первый экран: фото на всю ширину, имя поверх, как на афише */

/* «Макет на столе у дизайнера». Оба фоновых мотива взяты из самого фото: тонкая сетка повторяет
   стеклянные фасады башен, тёплое свечение — закат на оранжевой башне. Фото лежит отпечатком
   с белым полем, чуть криво; ровные метки реза показывают, где оно «должно» стоять.
   Стрелка ведёт от имени к фото. На телефоне всё в столбик: имя, строка о работе, фото, кнопка.
   На компьютере (см. ниже) текст слева, фото справа. */
.hero {
  --grid-step: 48px;
  --mark-gap: 22px;
  --mark-len: 12px;
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 20px var(--gutter) 36px;
  overflow: hidden;
  isolation: isolate;
  background: #f4f4f4;
}

/* Сетка: видна вокруг фото и растворяется к краям */
.hero::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  background-image:
    linear-gradient(to right, rgb(0 0 0 / 0.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgb(0 0 0 / 0.07) 1px, transparent 1px);
  background-size: var(--grid-step) var(--grid-step);
  background-position: var(--gutter) 20px;
  -webkit-mask-image: radial-gradient(ellipse 95% 70% at 62% 62%, #000 30%, transparent 100%);
  mask-image: radial-gradient(ellipse 95% 70% at 62% 62%, #000 30%, transparent 100%);
}

/* Обёртки текста растворены, чтобы фото встало между строкой о работе и кнопкой */
.hero__text,
.hero__info {
  display: contents;
}

.hero h1 {
  order: 1;
  font-size: clamp(2.1rem, 11.3vw, 4.6rem);
  line-height: 1.02;
  white-space: nowrap;
}

.hero__role {
  order: 2;
  max-width: 16em;
  margin-top: 14px;
  font-size: 1.25rem;
  line-height: 1.3;
}

.hero__photo {
  order: 3;
  position: relative;
  width: min(66%, 380px);
  margin: 44px 12px 44px auto;
}

/* Свечение за фото */
.hero__photo::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -70%;
  background: radial-gradient(closest-side, rgb(255 138 76 / 0.5), rgb(255 196 150 / 0.24) 52%, rgb(255 196 150 / 0));
}

.hero__photo img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 20%;
  border: 7px solid #fff;
  box-shadow: 0 20px 40px -18px rgb(90 40 10 / 0.5);
  transform: rotate(-3deg);
}

/* Метки реза: по две короткие линии у каждого угла, на продолжении краёв фото */
.hero__photo::after {
  --m: linear-gradient(var(--ink), var(--ink));
  content: "";
  position: absolute;
  inset: calc(-1 * var(--mark-gap));
  background:
    var(--m) left 0 top var(--mark-gap) / var(--mark-len) 1px no-repeat,
    var(--m) left var(--mark-gap) top 0 / 1px var(--mark-len) no-repeat,
    var(--m) right 0 top var(--mark-gap) / var(--mark-len) 1px no-repeat,
    var(--m) right var(--mark-gap) top 0 / 1px var(--mark-len) no-repeat,
    var(--m) left 0 bottom var(--mark-gap) / var(--mark-len) 1px no-repeat,
    var(--m) left var(--mark-gap) bottom 0 / 1px var(--mark-len) no-repeat,
    var(--m) right 0 bottom var(--mark-gap) / var(--mark-len) 1px no-repeat,
    var(--m) right var(--mark-gap) bottom 0 / 1px var(--mark-len) no-repeat;
  pointer-events: none;
}

/* Стрелка от имени к фото, цвет — закат на башне */
.hero__arrow {
  position: absolute;
  top: 6%;
  right: calc(100% + 16px);
  width: 78px;
  fill: none;
  stroke: #f0662b;
  stroke-width: 4.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}

.hero .btn {
  order: 4;
  width: 100%;
}

.hero .btn:hover {
  opacity: 0.82;
}

/* Работы */

.works {
  padding-block: var(--section);
}

.triptych {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-top: 32px;
}

.trip {
  display: block;
  color: inherit;
  text-decoration: none;
}

.trip__name {
  display: block;
  margin-top: 12px;
  font: 800 0.84rem/1.1 var(--display);
  letter-spacing: -0.03em;
}

.trip__who {
  display: block;
  margin-top: 2px;
  font-size: 0.9375rem;
  line-height: 1.25;
  color: var(--muted);
}

/* Рамки устройств заданы в процентах, чтобы пропорции держались при любом размере */
.phone {
  display: block;
  padding: 2.8%;
  border-radius: 13% / 6%;
  background: var(--ink);
}

.phone img {
  width: 100%;
  border-radius: 10.5% / 4.85%;
}

/* Телефоны в ряду из трёх работ сами листают сайт. Сначала виден обычный первый экран; когда лента
   всего сайта догрузится (main.js), она проявляется поверх и медленно едет вниз и обратно.
   Ленты — те же файлы, что открываются по кнопке «Показать сайт целиком». */
.phone__screen {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 780 / 1688;
  border-radius: 10.5% / 4.85%;
}

.phone__screen img {
  display: block;
  border-radius: 0;
}

.phone__reel {
  position: absolute;
  inset: 0 0 auto;
  display: block;
  opacity: 0;
  transition: opacity 0.6s;
  will-change: transform;
}

.phone__reel.is-ready {
  opacity: 1;
  animation: reel var(--reel-time, 70s) linear infinite alternate;
}

/* --travel задаёт main.js: высота экрана телефона минус высота ленты */
@keyframes reel {
  0%,
  4% {
    transform: translateY(0);
  }
  96%,
  100% {
    transform: translateY(var(--travel, 0));
  }
}

.laptop {
  padding-inline: 4.5%;
}

.laptop__screen {
  padding: 2.2% 2.2% 2.6%;
  border-radius: 2.6% / 4.1%;
  background: var(--ink);
}

.laptop__screen img {
  width: 100%;
  border-radius: 2px;
}

.laptop::after {
  content: "";
  display: block;
  height: 0;
  margin-inline: -4.9%;
  padding-top: 2%;
  border-radius: 0 0 10px 10px;
  background: var(--ink);
}

.work {
  margin-top: 56px;
  padding-top: 24px;
  border-top: 2px solid var(--ink);
  scroll-margin-top: 16px;
}

.work__head {
  display: grid;
  gap: 6px;
  margin-bottom: 24px;
}

.work__who {
  color: var(--muted);
}

.work__screens {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px 12px;
  align-items: end;
}

.work__screens .laptop {
  grid-column: 1 / -1;
}

/* «Показать сайт целиком»: длинная лента открывается по кнопке и до этого не загружается */

.full {
  margin-top: 24px;
}

.full summary,
.full__up {
  display: inline-flex;
  align-items: center;
  min-height: 52px;
  padding: 0 22px;
  border: 2px solid var(--ink);
  border-radius: var(--radius);
  background: none;
  color: inherit;
  font: 600 1.125rem/1 var(--text);
  cursor: pointer;
}

.full summary {
  list-style: none;
}

.full summary::-webkit-details-marker {
  display: none;
}

.full summary:hover,
.full__up:hover {
  background: var(--hover);
}

.full__close,
.full[open] .full__open {
  display: none;
}

.full[open] .full__close {
  display: inline;
}

.full__strip {
  width: min(100%, 390px);
  margin-top: 24px;
  padding: 10px;
  border-radius: 28px;
  background: var(--ink);
  overflow: hidden;
}

.full__strip img {
  width: 100%;
}

.full__strip img:first-child {
  border-radius: 20px 20px 0 0;
}

.full__strip img:last-child {
  border-radius: 0 0 20px 20px;
}

.full__up {
  margin-top: 16px;
}

/* Обо мне */

/* Линия сверху нарисована фоном, чтобы она шла по ширине текста, а не заходила на поля */
.about {
  padding-block: var(--section);
  background: linear-gradient(var(--ink), var(--ink)) top / calc(100% - 2 * var(--gutter)) 2px no-repeat;
}

.about__text {
  max-width: 28em;
  margin-top: 20px;
  font-size: 1.3125rem;
  line-height: 1.4;
}

/* Контакты */

.contact {
  padding-block: var(--section) 28px;
  background: #000;
  color: #fff;
}

.contact :focus-visible {
  outline-color: #fff;
}

.contact__row {
  display: grid;
  gap: 16px;
  margin-top: 32px;
}

.contact__nick {
  font-size: 1.25rem;
}

.footer {
  margin-top: 56px;
  padding-top: 20px;
  border-top: 1px solid rgb(255 255 255 / 0.2);
  font-size: 0.9375rem;
  color: #a8a8a8;
}

/* Планшет */

@media (min-width: 720px) {
  :root {
    --gutter: 32px;
    --section: 96px;
  }

  body {
    font-size: 1.1875rem;
  }

  .hero .btn {
    align-self: flex-start;
    width: auto;
  }

  .triptych {
    gap: 28px;
  }

  .trip__name {
    font-size: 1.16rem;
  }

  .trip__who {
    font-size: 1.0625rem;
  }

  .contact__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px 32px;
  }
}

/* Компьютер */

@media (min-width: 960px) {
  :root {
    --section: 128px;
    --gutter: 48px;
    /* левый край текста на первом экране совпадает с левым краем остальной страницы */
    --edge: max(var(--gutter), calc((100vw - 1344px) / 2 + var(--gutter)));
  }

  /* Первый экран на компьютере: текст слева, фото справа небольшой карточкой.
     Фото показывается меньше своего размера: пользователю не нравится любое увеличение снимка. */
  .hero {
    --photo-w: clamp(320px, 30vw, 480px);
    --grid-step: 80px;
    --mark-gap: 44px;
    --mark-len: 22px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--photo-w);
    align-items: center;
    column-gap: 64px;
    min-height: clamp(620px, 100vh, 860px);
    padding: 64px var(--edge);
  }

  .hero::after {
    background-position: var(--edge) 0;
    -webkit-mask-image: radial-gradient(ellipse 62% 95% at 76% 50%, #000 25%, transparent 100%);
    mask-image: radial-gradient(ellipse 62% 95% at 76% 50%, #000 25%, transparent 100%);
  }

  .hero__text {
    display: block;
    grid-column: 1;
    grid-row: 1;
  }

  .hero__info {
    display: block;
  }

  .hero h1 {
    font-size: min(5.4rem, 5.4vw);
  }

  .hero__role {
    margin-top: 28px;
    font-size: 1.75rem;
  }

  .hero .btn {
    margin-top: 36px;
  }

  .hero__photo {
    grid-column: 2;
    grid-row: 1;
    width: auto;
    margin: 0;
  }

  .hero__photo img {
    border-width: 10px;
    box-shadow: 0 28px 56px -24px rgb(90 40 10 / 0.5);
  }

  .hero__arrow {
    top: 61%;
    right: calc(100% + 26px);
    width: clamp(120px, 11.5vw, 210px);
    stroke-width: 3.5;
  }

  /* Заголовок слева, три сайта справа */
  .works__top {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.9fr);
    column-gap: 64px;
    align-items: start;
  }

  .triptych {
    gap: 32px;
    margin-top: 0;
  }

  .work {
    margin-top: 112px;
    padding-top: 32px;
  }

  .work__head {
    margin-bottom: 40px;
  }

  .work__screens {
    grid-template-columns: minmax(0, 1fr) 19% 19%;
    gap: 40px;
  }

  .work__screens .laptop {
    grid-column: auto;
  }

  .full {
    margin-top: 40px;
  }

  /* Заголовок слева, текст справа: строка занимает ширину, а не висит в пустоте */
  .about {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.9fr);
    column-gap: 64px;
    align-items: start;
  }

  .about__text {
    margin-top: 0.35em;
    font-size: 2rem;
    line-height: 1.3;
  }

  .contact h2 {
    font-size: 3.8rem;
  }

  .contact__row {
    margin-top: 48px;
  }

  .contact__nick {
    font-size: 1.5rem;
  }
}

/* Движение на первом экране. При открытии, один раз: проявляются метки реза и свечение,
   фото ложится на макет, стрелка дорисовывается от имени к фото. Дальше страница не замирает:
   свечение медленно дышит, фото едва покачивается, стрелка раз в пять секунд подаётся к фото.
   Всё выключено, если у посетителя в системе включено «уменьшение движения». */
@media (prefers-reduced-motion: no-preference) {
  .hero__photo::after {
    animation: hero-fade 0.5s 0.15s both;
  }

  .hero__photo::before {
    animation:
      hero-fade 1.4s 0.3s both,
      hero-breathe 9s 1.7s ease-in-out infinite alternate;
  }

  .hero__photo img {
    animation:
      hero-drop 0.75s 0.45s cubic-bezier(0.2, 0.9, 0.25, 1.15) both,
      hero-sway 7s 1.3s ease-in-out infinite alternate;
  }

  .hero__arrow {
    animation: hero-nudge 5s 2.4s ease-in-out infinite;
  }

  .hero__arrow path {
    stroke-dasharray: 1;
  }

  .hero__arrow-line {
    animation: hero-draw 0.7s 1.15s ease-in-out both;
  }

  .hero__arrow-head {
    animation: hero-draw 0.25s 1.8s ease-out both;
  }
}

@keyframes hero-fade {
  from {
    opacity: 0;
  }
}

@keyframes hero-drop {
  from {
    opacity: 0;
    transform: translateY(-22px) rotate(3deg) scale(1.05);
  }
  to {
    opacity: 1;
    transform: rotate(-3deg);
  }
}

@keyframes hero-draw {
  from {
    stroke-dashoffset: 1;
  }
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes hero-breathe {
  from {
    opacity: 0.85;
    transform: translate(-2%, 1%) scale(0.94);
  }
  to {
    opacity: 1;
    transform: translate(3%, -2%) scale(1.1);
  }
}

@keyframes hero-sway {
  from {
    transform: rotate(-3deg);
  }
  to {
    transform: rotate(-1.8deg) translateY(-5px);
  }
}

/* Почти всё время стрелка стоит, раз в пять секунд коротко подаётся к фото */
@keyframes hero-nudge {
  0%,
  78%,
  100% {
    transform: none;
  }
  86% {
    transform: translate(7px, -3px);
  }
  93% {
    transform: translate(-2px, 1px);
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}
