{
  "schemaVersion": 2,
  "version": "2026-10-28",
  "name": "GAJSIN",
  "palette": {
    "paper": "#E4E5DF",
    "ink": "#171717",
    "light": {
      "background": "#E4E5DF",
      "text": "#171717",
      "line": "#A7A7A7",
      "muted": "#555555",
      "surface": "#D3D3D3"
    },
    "dark": {
      "background": "#171717",
      "text": "#E4E5DF",
      "line": "#545454",
      "muted": "#B9B9B9",
      "surface": "#272727"
    },
    "dataRamp": {
      "usage": "Технологии на карте: от редких к частым",
      "light": [
        "#D3D3D3",
        "#B9B9B9",
        "#8C8C8C",
        "#5F5F5F",
        "#171717"
      ],
      "dark": [
        "#272727",
        "#484848",
        "#747474",
        "#A7A7A7",
        "#E4E5DF"
      ]
    }
  },
  "typography": {
    "display": {
      "family": "StMarie",
      "fallback": "serif",
      "weight": 100,
      "size": 80,
      "lineHeight": 88,
      "tracking": "-0.025em",
      "coverage": "Latin only",
      "font": "display"
    },
    "title": {
      "weight": 100,
      "size": 40,
      "lineHeight": 46,
      "tracking": "-0.025em",
      "coverage": "Latin only",
      "font": "display"
    },
    "heading": {
      "weight": 500,
      "size": 32,
      "lineHeight": 42,
      "tracking": "-0.03em",
      "font": "ui"
    },
    "body": {
      "family": "Martian",
      "fallback": "monospace",
      "weight": 400,
      "size": 16,
      "lineHeight": 26,
      "tracking": "0",
      "font": "ui"
    },
    "caption": {
      "weight": 400,
      "size": 13,
      "lineHeight": 20,
      "tracking": "0",
      "font": "ui"
    },
    "control": {
      "weight": 500,
      "size": 13,
      "lineHeight": 20,
      "tracking": "0",
      "font": "ui"
    },
    "fontStretch": "100%",
    "textStretch": "87.5%"
  },
  "spacing": {
    "unit": 4,
    "tight": 8,
    "controlX": 16,
    "card": 24,
    "content": 24,
    "section": 80,
    "pageDesktop": 32,
    "pageMobile": 24,
    "usage": {
      "unit": "Шаг сетки; между полем и подсказкой",
      "tight": "Иконка и текст; метка и поле; соседние действия",
      "controlX": "Внутренний отступ кнопки слева и справа",
      "card": "От края карточки до содержимого",
      "content": "Между смысловыми элементами карточки",
      "pageDesktop": "Минимальное поле страницы на широком экране",
      "pageMobile": "Поле страницы на телефоне",
      "section": "Между разделами",
      "compact": "Сжатые строки списков и внутренние отступы небольших элементов",
      "group": "Между группами элементов; заголовок и содержимое",
      "block": "От шапки до содержимого; перед каталогом и между крупными группами",
      "wide": "Крупный промежуток внутри самостоятельной сцены",
      "contact": "Вертикальное поле экрана контактов"
    },
    "compact": 12,
    "group": 32,
    "block": 48,
    "wide": 64,
    "contact": 96
  },
  "geometry": {
    "radius": 4,
    "border": 1,
    "focus": 2,
    "icon": 16,
    "scrollbar": 8,
    "iconStroke": 1.5,
    "contentMax": 1200,
    "iconLarge": 20,
    "brand": 28,
    "focusOffset": 3,
    "controlHeight": 48,
    "touchTarget": 44
  },
  "button": {
    "family": "filled-primary / outline-secondary / surface-filter",
    "disabledOpacity": 0.38,
    "spinnerSize": 12,
    "spinnerStroke": 1.5,
    "focusGeometry": "primary: external geometry.focus outline; secondary: same contour uses geometry.focus",
    "hoverGeometry": "immediate background and border contrast; no trace animation"
  },
  "motion": {
    "scale": {
      "s": 160,
      "m": 280,
      "l": 480,
      "usage": {
        "s": "Стрелки, галочка копирования, список фильтра, фон и контур карточки при наведении, уход страницы",
        "m": "Смена содержимого на месте, надпись кнопки, окно презентации, проявление сцены",
        "l": "Раскрытия и знак «+», перестройка сетки, вход страницы, появление при прокрутке, смена темы"
      }
    },
    "easing": "cubic-bezier(0.25,1,0.5,1)",
    "shift": {
      "s": 4,
      "l": 16
    },
    "stagger": 60,
    "press": {
      "distanceY": 1
    },
    "link": {
      "distanceX": 2,
      "distanceY": -2
    },
    "dialog": {
      "scale": 0.98
    },
    "spinner": {
      "duration": 800,
      "easing": "linear"
    },
    "letters": {
      "rise": 450,
      "return": 650,
      "stagger": 40,
      "easing": "outExpo",
      "distanceY": -20,
      "rotation": -12
    },
    "logo": {
      "draw": 800,
      "fill": 200,
      "exit": 120,
      "easing": "cubic-bezier(0.16,1,0.3,1)",
      "size": 128
    },
    "reducedMotion": "Нет заставки, кругового раскрытия темы, входа страницы, появления при прокрутке и смены содержимого; активные раскрытия, перестройки и буквы завершаются сразу при изменении настройки. Декоративные сцены выключены; содержание, действия и список технологий доступны.",
    "notFound": {
      "duration": 1100,
      "rowStagger": 40,
      "digitStagger": 60,
      "easing": "cubic-bezier(0.22,1,0.36,1)"
    },
    "feedback": {
      "iconScale": 0.6,
      "messageDuration": 1600
    },
    "scenePolicy": "Непрерывные Canvas/WebGL-сцены имеют собственные физические параметры в скачиваемых исходниках. Общая шкала S/M/L управляет интерфейсом, а не скоростью физической симуляции. Сцены останавливаются вне экрана и в скрытой вкладке; reduced motion сохраняет содержимое без запуска сцен."
  },
  "interaction": {
    "sound": false,
    "accent": false,
    "navigation": "top",
    "darkToLight": "Immediate icon toggle without confirmation",
    "code": "Display source, dependencies, license and integration instructions; copy only user-selected code",
    "accessibility": [
      "Навигация клавишей Tab, видимый фокус и смысловые HTML-элементы.",
      "Открытие Enter или Space; Escape закрывает список и окно; стрелки выбирают вариант в списке.",
      "Движение не задерживает действие. Повторный клик прерывает переход с текущего кадра.",
      "Reduced motion действует сразу при изменении настройки; содержимое и действия остаются доступны.",
      "Минимальная цель касания geometry.touchTarget; основные контролы geometry.controlHeight."
    ]
  },
  "responsive": {
    "breakpoint": 720,
    "display": {
      "size": 48,
      "lineHeight": 54
    },
    "heading": {
      "size": 26,
      "lineHeight": 36
    },
    "section": 48
  },
  "components": {
    "buttons": {
      "primary": "filled",
      "secondary": "outline",
      "filter": "surface + label + chevron",
      "light": {
        "primaryHover": "#3D3D3D",
        "primaryPressed": "#555555",
        "secondaryHover": "#C4C4C4",
        "secondaryPressed": "#B9B9B9",
        "filterHover": "#B9B9B9",
        "filterPressed": "#A7A7A7"
      },
      "dark": {
        "primaryHover": "#B9B9B9",
        "primaryPressed": "#A7A7A7",
        "secondaryHover": "#3D3D3D",
        "secondaryPressed": "#545454",
        "filterHover": "#484848",
        "filterPressed": "#545454"
      }
    },
    "fields": {
      "backgroundRole": "surface",
      "borderRole": "muted",
      "hoverBorderRole": "text",
      "invalidStyle": "2px dashed + icon + message",
      "menuMaxHeight": 260,
      "geometry": "Общая высота geometry.controlHeight; иконка geometry.icon; боковой отступ spacing.controlX; между полем и меню spacing.tight; рамка geometry.border, фокус geometry.focus."
    },
    "cards": {
      "types": [
        "information",
        "media",
        "interactive"
      ],
      "mediaRatio": "1 / 1",
      "layout": "two equal-height text cards; full-width media row; single column on mobile",
      "thumbnail": 96,
      "thumbnailMobile": 72
    },
    "disclosure": {
      "duration": "l",
      "textMaxHeight": 560,
      "codeHeight": 400,
      "behavior": "Одинаковое изменение полной высоты при открытии и закрытии. Повторный клик продолжает с текущей высоты; рамки и отступы входят в расчёт; загрузившийся текст раскрывается тем же механизмом.",
      "source": "design-system/disclosure-motion.js"
    },
    "tabs": {
      "duration": "m",
      "behavior": "Выбор меняется сразу; новое содержимое проявляется со сдвигом 16 px. Файлы исходников используют тот же переход без сброса фокуса."
    },
    "dialog": {
      "inset": 16,
      "backdropOpacity": 0.6,
      "duration": "m",
      "behavior": "Нативное модальное окно: фокус внутри; Escape, закрытие и клик по затемнению возвращают фокус к кнопке открытия. Iframe сохраняется до конца ухода и затем выгружается. Ширина ограничена geometry.contentMax."
    },
    "layoutMotion": {
      "source": "design-system/layout-motion.js",
      "duration": "l",
      "behavior": "Один механизм для сетки, списка и фильтров. Повторный переход начинается с текущих визуальных координат; карточки не масштабируются. Новые элементы проявляются, видимые сохраняют непрерывность. При смене размера и reduced motion переход завершается."
    },
    "navigation": {
      "position": "sticky",
      "behavior": "Общая шапка остаётся у верхнего края на всех экранах; якоря учитывают её высоту и безопасную область. Текущий пункт обозначен начертанием и aria-current. Ссылки доступны во время перехода; последний выбор не теряется."
    },
    "icons": {
      "geometry": "geometry.icon / geometry.iconLarge, штрих geometry.iconStroke; интерактивная зона geometry.controlHeight. Знак плюса расположен рядом с подписью.",
      "behavior": "Декоративные SVG скрыты от скринридера; у кнопки без текста есть доступное имя. Внешняя ссылка отмечена стрелкой. Иконки браузера генерируются из одного логотипа и следуют теме документа."
    },
    "feedback": {
      "behavior": "Подтверждение копирования — текст role=status и галочка; ошибка остаётся сообщением с понятным действием. Загрузка отмечена aria-busy; недоступность — disabled, а не только цветом.",
      "duration": "motion.scale.s для значка; motion.feedback.messageDuration для галочки"
    }
  },
  "layout": {
    "header": 80,
    "headerMobile": 128,
    "headerCompact": 176,
    "breakpoints": {
      "tablet": 1023,
      "compact": 374,
      "portrait": 900
    },
    "columns": {
      "desktop": 3,
      "tablet": 2,
      "mobile": 1
    },
    "textMeasure": "70ch",
    "referenceHeader": 72,
    "referenceHeaderMobile": 64
  },
  "contract": {
    "source": "design-system/tokens.json",
    "build": "npm run design:build && npm run site:prepare",
    "check": "npm run check && npm run design:check",
    "scope": "Общая оболочка, интерфейс, компоненты и переходы портфолио. Изображения и HTML-презентации сохраняют оформление соответствующих продуктов; их полоса прокрутки и иконки наследуются при сборке.",
    "fonts": "Семейство UI задаётся в typography.body.family, выразительное семейство — в typography.display.family; остальные роли ссылаются на них через font. После смены семейства добавьте WOFF2 и обновите @font-face в site.css и design-system.css."
  },
  "layers": {
    "header": 30,
    "intro": 9999,
    "skipLink": 10000,
    "dialog": "browser top layer"
  }
}
