/* ============================================================
   Портфолио Мурсала Мурсалова — токены
   Этап 4. Правила и обоснования — design/CANON.md
   Единственный источник значений. Хардкод цвета мимо токена — баг.
   ============================================================ */

:root {
  /* ---------- Шрифт ---------- */
  --font: "Inter Variable", Inter, -apple-system, BlinkMacSystemFont,
          "Segoe UI", system-ui, sans-serif;

  /* ---------- Типографика ----------
     Сетка 4px без исключений.
     Кегли        12 · 16 · 20 · 24 · 32  →  4 × (3 · 4 · 5 · 6 · 8)
     Межстрочные  16 · 24 · 28 · 32 · 40  →  4 × (4 · 6 · 7 · 8 · 10)
     Пять кеглей, семь ролей: body/strong делят 16, meta/micro делят 12. */
  --text-display:      2rem;      /* 32 */
  --text-display-lh:   2.5rem;    /* 40 */
  --text-display-w:    600;
  --text-display-ls:   -0.02em;
  --text-display-mb:   24px;

  --text-title:        1.5rem;    /* 24 */
  --text-title-lh:     2rem;      /* 32 */
  --text-title-w:      600;
  --text-title-ls:     -0.02em;
  --text-title-mb:     16px;

  --text-lead:         1.25rem;   /* 20 */
  --text-lead-lh:      1.75rem;   /* 28 */
  --text-lead-w:       500;
  --text-lead-ls:      -0.01em;
  --text-lead-mb:      12px;

  --text-body:         1rem;      /* 16 */
  --text-body-lh:      1.5rem;    /* 24 */
  --text-body-w:       400;
  --text-body-ls:      -0.01em;
  --text-body-mb:      16px;      /* абзац → абзац */

  --text-strong-w:     550;       /* тот же кегль, что body */
  --text-strong-mb:    8px;

  --text-meta:         0.75rem;   /* 12 */
  --text-meta-lh:      1rem;      /* 16 */
  --text-meta-w:       500;
  --text-meta-ls:      0;
  --text-meta-mb:      8px;

  --text-micro:        0.75rem;   /* 12 — тот же кегль, что meta */
  --text-micro-lh:     1rem;      /* 16 */
  --text-micro-w:      600;
  --text-micro-ls:     0.04em;    /* рассчитан на прописные */
  --text-micro-mb:     8px;

  /* Кегль кнопки — исключение из шкалы, снят с макета (узел 2009:498).
     14 не кратно четырём и в пятёрку кеглей не входит. Оставлен, потому
     что автор дважды сказал «кнопки как в макете». Ждёт подтверждения. */
  --text-btn:          0.875rem;  /* 14 */
  --text-btn-lh:       1.25rem;   /* 20 */
  --text-btn-w:        600;

  /* ---------- Сетка ---------- */
  --col:        610px;
  --measure:    545px;
  --rail-w:     244px;
  --rail-left:  40px;
  --page-pad:   24px;

  /* ---------- Отступы ----------
     Шкала мелких величин. Все кратны 4.                        */
  --s-1:   4px;   --s-2:   8px;   --s-3:  12px;  --s-4:  16px;
  --s-5:  20px;   --s-6:  24px;   --s-7:  32px;  --s-8:  48px;
  --s-9:  64px;

  /* Вертикальный ритм страницы — снят с макета в Figma, узел 2009:219.
     Это не ступени шкалы, а именованные роли: расстояние между
     разделами не выбирается из набора, оно у каждого стыка своё.
     Все значения кратны 4.                                      */
  --gap-inline:     var(--s-3);   /* 12  кнопки между собой               */
  --gap-card:       var(--s-5);   /* 20  карточки в ряду                  */
  --gap-card-meta:  var(--s-5);   /* 20  карточка → её мета-строка        */
  --gap-meta-next:  40px;         /* 40  мета-строка → следующая карточка */
  --gap-label:      16px;         /* 16  ярлык секции → содержимое        */
  --gap-text:       var(--s-7);   /* 32  текст → кнопки                   */
  --gap-block:      44px;         /* 44  блок → блок внутри раздела       */
  --gap-head:       40px;         /* 40  шапка → первый блок              */
  --gap-tst:        var(--s-6);   /* 24  вокруг подписи автора отзыва     */
  --gap-icon:       6px;          /* 6   поле по краям ссылки с иконкой   */
  --rail-sticky:    80px;         /* 80  липкая метка → верх экрана       */
  --rail-tail:     200px;         /* 200 метка едет ниже своего раздела   */
  --shot-phone:    520px;         /* 520 высота мобильного скриншота      */
  --gap-case:        80px;        /* 80  блок → блок на странице кейса    */
  --gap-section:    112px;        /* 112 перед разделом работ             */
  --gap-section-lg: 140px;        /* 140 между крупными разделами         */
  --gap-section-sm: var(--s-9);   /* 64  то же на мобильном               */
  --page-top:       100px;        /* 100 верх страницы → первый блок      */
  --gap-page-end:   120px;        /* 120 низ тёмного блока → конец сайта  */
  --toc-left:       100px;        /* 100 содержание кейса → левый край    */

  /* ---------- Радиусы ----------
     Тоже на сетке 4px: 17 и 18 из замеров этапа 2 сведены к 16.  */
  --r-xs:   2px;   /* черточки рельса                       */
  --r-sm:   8px;   /* кнопка, строка рельса                 */
  --r-md:  12px;   /* плитка, видео, фото внутри рамки      */
  --r-lg:  16px;   /* рамка аватара, строка с выносом       */
  --r-xl:  20px;   /* карточка, модалка                     */
  --r-full: 999px; /* кружок темы                           */

  /* «Эпловское» скругление — squircle. У обычного радиуса кривизна
     постоянная, и на маленьких размерах угол читается обрубленным.
     Здесь кривизна нарастает плавно. Это маска, а не border-radius:
     задаётся один раз токеном, чтобы форма была одинаковой везде. */
  --squircle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cpath fill='%23000' d='M0 50C0 15.6 15.6 0 50 0s50 15.6 50 50-15.6 50-50 50S0 84.4 0 50Z'/%3E%3C/svg%3E");

  /* ---------- Движение ---------- */
  --ease:       cubic-bezier(0, 0, .2, 1);
  --ease-enter: cubic-bezier(.22, 1, .36, 1);
  --ease-morph: cubic-bezier(.19, 1, .22, 1);
  /* Разгон, а не торможение: значение держится маленьким и добирает
     в конце. Нужен там, где ход считает прокрутка, а эффект должен
     доходить до предела в самом конце пути.

     Кривая мягкая намеренно — на полпути даёт около трети хода.
     Резкий разгон (.5, 0, .85, .45) автор забраковал как слишком
     медленный, равномерный — как слишком быстрый.                    */
  --ease-in:    cubic-bezier(.42, 0, .72, .62);

  --dur-fast:  150ms;
  --dur-base:  200ms;
  --dur-enter: 260ms;
  --dur-slow:  400ms;

  /* ---------- Цвет · светлая тема ----------
     Значения ниже — база. Тёмная переопределяет ТОЛЬКО этот блок. */
  --canvas:    #FCFCFC;
  --surface:   #FFFFFF;
  --ink:       #202020;
  --ink-hover: #000000;
  --body-c:    #424242;
  --muted:     #646464;
  --hairline:  rgba(32, 32, 32, .10);
  --underline: #D9D9D9;
  --hover:     #F6F6F6;
  /* Поле подложки. Отдельный токен, а не --hover: по ревью «цвета
     подложки отличаются, мой грязнее». Референс кладёт подложку
     цветом страницы, отделяет её тень, а не заливка. --hover заметно
     серее и пачкал белую плашку поверх.                             */
  --plate:     var(--canvas);
  --focus:     #315EFB;

  /* Тёмный блок Lab — одинаковый в обеих темах */
  --lab:       #050505;
  --lab-ink:   rgba(255, 255, 255, .90);
  --lab-muted: rgba(255, 255, 255, .55);
  --lab-media: #252525;
  --lab-plate: #131313;   /* поле подложки под плиткой Lab */

  --shadow-card:
    0 0 0 1px rgba(0, 0, 0, .06),
    0 1px 2px -1px rgba(0, 0, 0, .06),
    0 2px 4px 0 rgba(0, 0, 0, .04);

  --shadow-toast:
    0 22px 55px rgba(35, 61, 56, .16),
    0 8px 22px  rgba(35, 61, 56, .12),
    inset 0 1px 0 rgba(255, 255, 255, .9);

  /* На тёмном тень не работает — работает внутренняя светлая линия.
     Отдельный токен, а не то же имя с другим значением.            */
  --shadow-dark:
    inset 0 0 0 1px rgba(255, 255, 255, .067),
    inset 0 1px 0   rgba(255, 255, 255, .08);

  --toast-bg: rgba(255, 255, 255, .94);

  /* Тень кнопки — скевоморфная, из макета. Четвёртая тень на сайте,
     правило «три тени» нарушено осознанно. Ждёт подтверждения.      */
  --shadow-btn:
    0 1px 2px 0 rgba(16, 24, 40, .05),
    inset 0 0 0 1px rgba(16, 24, 40, .18),
    inset 0 -2px 0 0 rgba(16, 24, 40, .05);

  --btn-border: #DBDBDB;   /* контур второстепенной кнопки, из макета */

  /* Ширина тёмного блока Experiments and Lab — шире колонки.
     990 = 4 плитки по 240 плюс три зазора по 10, как в лоу-фае.     */
  --lab-w: 990px;

  color-scheme: light dark;
}

/* ---------- Цвет · тёмная тема ----------
   Системная настройка, если пользователь не выбрал светлую явно. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --canvas:    #101010;
    --surface:   #1A1A1A;
    --ink:       #F2F2F0;
    --ink-hover: #FFFFFF;
    --body-c:    #C8C8C6;
    --muted:     #7D7D7D;
    --hairline:  rgba(255, 255, 255, .11);
    --underline: #3A3A3A;
    --hover:     #1F1F1F;
    --focus:     #8EB0FF;

    --shadow-card: var(--shadow-dark);
    --toast-bg:    rgba(38, 38, 38, .94);
    --btn-border:  rgba(255, 255, 255, .16);
    --shadow-btn:
      0 1px 2px 0 rgba(0, 0, 0, .4),
      inset 0 0 0 1px rgba(255, 255, 255, .14),
      inset 0 -2px 0 0 rgba(0, 0, 0, .25);
  }
}

/* Явный выбор пользователя перекрывает системный в обе стороны. */
:root[data-theme="dark"] {
  --canvas:    #101010;
  --surface:   #1A1A1A;
  --ink:       #F2F2F0;
  --ink-hover: #FFFFFF;
  --body-c:    #C8C8C6;
  --muted:     #7D7D7D;
  --hairline:  rgba(255, 255, 255, .11);
  --underline: #3A3A3A;
  --hover:     #1F1F1F;
  --focus:     #8EB0FF;

  --shadow-card: var(--shadow-dark);
  --toast-bg:    rgba(38, 38, 38, .94);
  --btn-border:  rgba(255, 255, 255, .16);
  --shadow-btn:
    0 1px 2px 0 rgba(0, 0, 0, .4),
    inset 0 0 0 1px rgba(255, 255, 255, .14),
    inset 0 -2px 0 0 rgba(0, 0, 0, .25);
}

/* ---------- Точки перелома ---------- */
@media (max-width: 1279px) {
  :root { --rail-left: 0px }   /* рельс уходит в поток */
}

@media (max-width: 767px) {
  :root {
    --page-pad:        var(--s-5);   /* 20 */
    --page-top:        var(--s-9);   /* 64 */
    --gap-head:        var(--s-8);   /* 48 */
    --gap-section:     var(--gap-section-sm);   /* 64 */
    --gap-section-lg:  80px;
    --text-display:    1.75rem;      /* 28 — 32 в узкой колонке даёт четыре строки */
    --text-display-lh: 2.25rem;      /* 36 — остаётся на сетке 4px */
  }
}

/* ---------- Смена темы: радиальная волна ----------
   Механика снята с madebyvishesh.com: новая тема открывается мягким
   круговым проявлением из точки, где стоит переключатель.
   Замерено — View Transitions API, 0.92s, cubic-bezier(.19,1,.22,1),
   маска radial-gradient с растушёвкой на 36 / 72 / 120px.          */
@property --wipe-r { syntax: "<length>"; inherits: false; initial-value: 0px }

::view-transition-old(root),
::view-transition-new(root) { mix-blend-mode: normal; pointer-events: none }

/* Старый кадр стоит на месте, новый наезжает поверх. */
::view-transition-old(root) { animation: none; z-index: 1 }
::view-transition-new(root) {
  z-index: 2;
  animation: theme-wipe .92s cubic-bezier(.19, 1, .22, 1) both;
  mask-image: radial-gradient(circle at var(--wipe-x, 50%) var(--wipe-y, 50%),
    #000 0 var(--wipe-r),
    rgba(0,0,0,.72) calc(var(--wipe-r) + 36px),
    rgba(0,0,0,.32) calc(var(--wipe-r) + 72px),
    transparent      calc(var(--wipe-r) + 120px));
}
@keyframes theme-wipe { from { --wipe-r: 0px } to { --wipe-r: var(--wipe-max, 150vmax) } }

/* Сам кружок переключателя переезжает отдельной парой. */
::view-transition-group(theme-icon) { z-index: 4; pointer-events: none }
::view-transition-old(theme-icon) { animation: theme-icon-out .12s ease-out both }
::view-transition-new(theme-icon) { animation: theme-icon-in .36s cubic-bezier(.19, 1, .22, 1) both }
@keyframes theme-icon-out { to { opacity: 0; transform: scale(.86) rotate(-16deg) } }
@keyframes theme-icon-in  { from { opacity: 0; transform: scale(.86) rotate(16deg) } }

/* ---------- База ---------- */
*, *::before, *::after { box-sizing: border-box }

html { -webkit-text-size-adjust: 100% }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--body-c);
  font-family: var(--font);
  font-size: var(--text-body);
  line-height: var(--text-body-lh);
  font-weight: var(--text-body-w);
  letter-spacing: var(--text-body-ls);
  -webkit-font-smoothing: antialiased;
}

/* ---------- Смена темы происходит мгновенно ----------
   Не по вкусу, а по устройству браузера. Если у свойства значение
   взято из var() и на него навешан transition, то при смене custom
   property свойство НЕ переразрешается: оно застревает на значении,
   захваченном при первой отрисовке. Проверено на прототипе — фон
   страницы оставался тёмным при любом data-theme.

   Ловушка касается каждого места, где тема меняет цвет, на котором
   висит переход: фон страницы, черточки рельса, кнопки, ссылки,
   переключатели. Поэтому переходы глушатся на время переключения,
   а не лечится один body.

   Ховеры, фокус и всё остальное движение при этом не трогаются. */
.theme-switching,
.theme-switching *,
.theme-switching *::before,
.theme-switching *::after { transition: none !important }

::selection {
  background: color-mix(in srgb, var(--ink) 12%, transparent);
  color: var(--ink);
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
:focus:not(:focus-visible) { outline: none }

/* Годы и мета-строки должны вставать в колонку. */
.meta, .year, time { font-variant-numeric: tabular-nums }

/* ---------- Доступность движения ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    scroll-behavior: auto !important;
    transition-property: color, background-color, border-color,
                         opacity, text-decoration-color, outline-color !important;
    transition-duration: var(--dur-fast) !important;
  }
  /* Волна темы тоже отключается — тема просто меняется. */
  ::view-transition-old(root),
  ::view-transition-new(root),
  ::view-transition-old(theme-icon),
  ::view-transition-new(theme-icon) { animation: none !important }
  ::view-transition-new(root) { mask-image: none !important }
}
