<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:media="http://search.yahoo.com/mrss/"
	
	>

<channel>
	<title>Nikita Vasilevskiy</title>
	<link>https://nikitavasilevskiy.com</link>
	<description>Nikita Vasilevskiy</description>
	<pubDate>Mon, 11 May 2026 17:28:16 +0000</pubDate>
	<generator>https://nikitavasilevskiy.com</generator>
	<language>en</language>
	
		
	<item>
		<title>tryappka-beta</title>
				
		<link>https://nikitavasilevskiy.com/tryappka-beta</link>

		<pubDate>Fri, 27 Mar 2026 14:36:56 +0000</pubDate>

		<dc:creator>Nikita Vasilevskiy</dc:creator>

		<guid isPermaLink="true">https://nikitavasilevskiy.com/tryappka-beta</guid>

		<description>
      

        (function () {
          if (document.querySelector('meta[name="viewport"]')) return;
          var m = document.createElement("meta");
          m.setAttribute("name", "viewport");
          m.setAttribute(
            "content",
            "width=device-width, initial-scale=1, viewport-fit=cover, maximum-scale=5"
          );
          (document.head &#124;&#124; document.documentElement).appendChild(m);
        })();
      

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

      :root {
        --app-bg-color: #000000;
        --app-bg-image: none;
        --bg-image-preview-size: 60px;
        --bg-image-checker-size: 30px;
        --accent-lime: #ccff00;
        --ui-surface: #f0f0f0;
        --text-dark: #232323;
        /* Текст/заголовки прямо на поле фона приложения (см. syncUiTheme в main.js). */
        --on-app: #f0f0f0;
        --toggle-dot-bg: #f0f0f0;
        --stats-fg: rgba(255, 255, 255, 0.25);
        --font-label: Inter, "Helvetica Neue", Helvetica, system-ui, sans-serif;
        --version-fg: rgba(255, 255, 255, 0.25);
        --toggle-mark: #232323;
        --btn-export: #00aae3;
        --btn-upload: #00ab4a;
        --btn-reset: #ffcccc;
        --btn-clear: #eb6568;
        --gap-tight: 2px;
      }

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

      html,
      body {
        margin: 0;
        width: 100%;
        font-family: Inter, "Helvetica Neue", Helvetica, system-ui, sans-serif;
        -webkit-user-select: none;
        user-select: none;
        -webkit-touch-callout: none;
      }

      /* Фон только пока живёт .app (класс вешает tryappka.js). См. Рецепты/CARGO_SPA_NAVIGATION.md */
      html.tryappka-scope,
      html.tryappka-scope body {
        background: #232323;
      }

      html.tryappka-scope body.gp-recording::after {
        content: "";
        position: fixed;
        right: 24px;
        bottom: 24px;
        z-index: 2147483647;
        width: 36px;
        height: 36px;
        border-radius: 999px;
        background: #ff1d1d;
        pointer-events: none;
        animation: gp-rec-pulse 1.1s ease-in-out infinite;
      }

      @keyframes gp-rec-pulse {
        0%, 100% { opacity: 1; }
        50% { opacity: 0.35; }
      }

      .pinned.pinned_bottom .page_container.overlay {
        display: none;
      }

      .site-avatar {
        display: none !important;
      }

      .app {
        box-sizing: border-box;
        min-height: 100vh;
        min-height: 100dvh;
        height: 100vh;
        height: 100dvh;
        max-height: 100vh;
        max-height: 100dvh;
        overflow: hidden;
        overscroll-behavior: none;
        display: grid;
        grid-template-columns: 420px 1fr;
        grid-template-rows: minmax(0, 1fr);
        gap: var(--gap-tight);
        background-color: var(--app-bg-color);
      }

      .app &#62; .sidebar {
        grid-column: 1;
        grid-row: 1;
      }

      .app &#62; .preview {
        grid-column: 2;
        grid-row: 1;
        min-height: 0;
        display: flex;
        flex-direction: column;
      }

      @media (min-width: 1025px) {
        html.tryappka-scope,
        html.tryappka-scope body {
          height: 100%;
          overflow: hidden;
          overscroll-behavior: none;
        }

        .app &#62; .sidebar {
          min-height: 0;
          overflow-y: auto;
          overscroll-behavior: contain;
          -webkit-overflow-scrolling: touch;
        }
      }

      /* Резерв под строку версии под канвасом (при ui-hidden теперь скрыта вместе с остальным chrome). */
      .app-version-chrome-hidden {
        display: none !important;
      }

      /* Avoid first paint with Pro-only rows visible; fade in after JS shell init. */
      .app:not(.app-ready) {
        opacity: 0;
      }

      .app.app-ready {
        opacity: 1;
        transition: opacity 0.2s ease-out;
      }

      @media (prefers-reduced-motion: reduce) {
        .app.app-ready {
          transition: none;
        }
      }

      .app.ui-hidden {
        grid-template-columns: 1fr;
        grid-template-rows: minmax(0, 1fr);
        gap: 0;
        height: 100vh;
        height: 100dvh;
        max-height: 100vh;
        max-height: 100dvh;
        overflow: hidden;
      }

      .app.ui-hidden .sidebar {
        display: none;
      }

      .app.ui-hidden &#62; .preview {
        grid-column: 1;
        grid-row: 1;
        min-height: 0;
        overflow: hidden;
      }

      .app.ui-hidden &#62; .app-version-chrome-hidden {
        display: none !important;
      }

      .app.ui-hidden .stats {
        /* Keep FPS tappable even when UI is hidden. */
        display: block !important;
        pointer-events: auto !important;
      }

      .app.ui-hidden #preview-area {
        min-height: 0;
      }

      html.ui-chrome-hidden,
      body.ui-chrome-hidden {
        height: 100%;
        max-height: 100dvh;
        overflow: hidden;
      }

      .sidebar {
        background: transparent;
        display: flex;
        flex-direction: column;
        padding: 12px;
        gap: 0;
        min-height: 0;
        scrollbar-width: none;
        -ms-overflow-style: none;
      }

      .sidebar::-webkit-scrollbar {
        display: none;
        width: 0;
        height: 0;
      }

      .sidebar &#62; .ui {
        flex: 0 0 auto;
      }

      /* Свободная высота колонки — уходит в зазор над версией; переполнение — вплотную к управлению. */
      .sidebar &#62; .app-version {
        flex-shrink: 0;
        margin-top: auto;
      }

      .ui {
        display: flex;
        flex-direction: column;
        gap: var(--gap-tight);
        color: var(--text-dark);
      }

      .ui,
      .ui * {
        font-family: Inter, "Helvetica Neue", Helvetica, system-ui, sans-serif !important;
        letter-spacing: 0 !important;
        font-size: 20px;
        line-height: 20px;
        font-weight: 500 !important;
      }

      .app,
      .app * {
        -webkit-user-select: none !important;
        user-select: none !important;
        -webkit-touch-callout: none !important;
      }

      .corner-ui-toggle {
        -webkit-user-select: none !important;
        user-select: none !important;
        -webkit-touch-callout: none !important;
        display: none;
        position: fixed;
        width: 60px;
        height: 60px;
        z-index: 50;
        touch-action: none;
        -webkit-tap-highlight-color: transparent;
        pointer-events: auto;
        box-sizing: border-box;
        background: transparent;
      }

      .corner-ui-toggle.corner-ui-toggle--show {
        display: block;
      }

      .corner-ui-toggle--tl {
        top: env(safe-area-inset-top, 0px);
        left: env(safe-area-inset-left, 0px);
      }

      .corner-ui-toggle--tr {
        top: env(safe-area-inset-top, 0px);
        right: env(safe-area-inset-right, 0px);
        left: auto;
      }

      #preview-area,
      #preview-area canvas {
        -webkit-user-select: none !important;
        user-select: none !important;
        -webkit-touch-callout: none !important;
      }

      .stats {
        -webkit-user-select: none !important;
        user-select: none !important;
        pointer-events: auto;
        cursor: pointer;
      }

      .ui button,
      .ui .option {
        font-weight: 500;
      }

      button {
        -webkit-appearance: none;
        appearance: none;
        outline: none;
        box-shadow: none;
        -webkit-user-select: none;
        user-select: none;
      }

      button:focus,
      button:focus-visible,
      button:active {
        outline: none;
        box-shadow: none;
      }

      .upload-row {
        display: grid;
        grid-template-columns: 1fr;
        gap: var(--gap-tight);
        align-items: center;
      }

      .action-row {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: var(--gap-tight);
      }

      .control-group {
        display: flex;
        flex-direction: column;
        gap: var(--gap-tight);
      }

      .control-group + .control-group {
        margin-top: 8px;
      }

      .group-heading {
        margin: 0 0 8px;
        padding: 0;
        color: var(--on-app);
        font-size: 20px;
        line-height: 20px;
        font-weight: 500;
        letter-spacing: 0 !important;
        display: flex;
        align-items: center;
        justify-content: flex-start;
        gap: 10px;
        cursor: pointer;
      }

      /* Cargo can override generic heading/text styles aggressively. */
      .app .group-heading,
      .app h2.group-heading {
        display: flex !important;
        visibility: visible !important;
        opacity: 1 !important;
        color: var(--on-app) !important;
        font-family: Inter, "Helvetica Neue", Helvetica, system-ui, sans-serif !important;
        font-size: 20px !important;
        line-height: 20px !important;
        font-weight: 500 !important;
        letter-spacing: 0 !important;
        text-transform: none !important;
      }

      .group-heading .toggle-dot {
        width: 20px;
        height: 20px;
        border-radius: 999px;
        background: var(--toggle-dot-bg);
        position: relative;
        flex: 0 0 auto;
      }

      .group-heading .toggle-bar-h {
        position: absolute;
        width: 8px;
        height: 2px;
        background: var(--toggle-mark);
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
      }

      .group-heading .toggle-bar-v {
        position: absolute;
        width: 2px;
        height: 10px;
        background: var(--toggle-mark);
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%) scaleY(1);
        opacity: 1;
        transition:
          opacity 0.22s cubic-bezier(0.33, 0, 0.2, 1),
          transform 0.26s cubic-bezier(0.34, 0.82, 0.3, 1);
      }

      .control-group:not(.collapsed) .group-heading .toggle-bar-v {
        opacity: 0;
        transform: translate(-50%, -50%) scaleY(0.2);
        pointer-events: none;
      }

      .control-group-panel {
        display: grid;
        grid-template-rows: 1fr;
        transition: grid-template-rows 0.3s cubic-bezier(0.32, 0.72, 0, 1);
      }

      .control-group.collapsed .control-group-panel {
        grid-template-rows: 0fr;
        pointer-events: none;
      }

      .control-group-panel-inner {
        min-height: 0;
        overflow: hidden;
        display: flex;
        flex-direction: column;
        gap: var(--gap-tight);
        opacity: 1;
        transition: opacity 0.26s cubic-bezier(0.33, 1, 0.32, 1);
      }

      .control-group.collapsed .control-group-panel-inner {
        opacity: 0;
      }

      @media (prefers-reduced-motion: reduce) {
        .control-group-panel,
        .control-group-panel-inner {
          transition-duration: 0.05s;
        }

        .group-heading .toggle-bar-v {
          transition-duration: 0.05s;
        }
      }

      .app.ui-mode-basic .control-group[aria-label="Simulation"] {
        display: none;
      }

      .app.ui-mode-basic .normal-map-row {
        display: none;
      }

      .app.ui-mode-basic .control-group[aria-label="Back side"],
      .app.ui-mode-basic .control-group[aria-label="Background"] {
        display: none;
      }

      /* Hide temporary lighting UI from interface (presets are kept in files). */
      .control-group[aria-label="Lighting override"] {
        display: none !important;
      }

      .light-knob {
        display: none !important;
      }

      .app.ui-mode-basic [data-control="meshQuality"] .option[data-value="ultra"] {
        display: none;
      }

      .ui button:not(.option) {
        border: none;
        border-radius: 999px;
        height: 60px;
        padding: 0 2px 0 20px;
        cursor: pointer;
        color: var(--text-dark);
      }

      .ui button:not(.option):hover {
        filter: brightness(0.96);
      }

      .mode-switch {
        margin-bottom: 8px;
        width: 100%;
      }

      .mode-switch .options {
        display: flex;
        width: 100%;
        height: 60px;
        gap: 2px;
      }

      .mode-switch .option {
        flex: 1 1 50%;
        border-radius: 999px;
      }

      .controls {
        display: grid;
        gap: var(--gap-tight);
      }

      .control {
        display: grid;
        grid-template-columns: 112px minmax(0, 1fr);
        align-items: center;
        gap: 0;
        height: 60px;
        padding: 0;
        min-width: 0;
      }

      .control &#62; span {
        padding-left: 20px;
        min-width: 0;
      }

      .control,
      .color-control,
      .color-control .label,
      .bg-card,
      .bg-row,
      .option {
        background: var(--ui-surface);
      }

      .color-control {
        width: 100%;
        height: 60px;
        display: flex;
        flex-wrap: nowrap;
        align-items: stretch;
        overflow: hidden;
        position: relative;
        gap: 2px;
      }

      .color-control .label-wrap {
        flex: 1 1 0;
        display: flex;
        justify-content: flex-start;
        align-items: center;
      }

      .color-control .label {
        flex: 1 1 0;
        box-sizing: border-box;
        height: 60px;
        padding: 20px;
        display: flex;
        align-items: center;
        gap: 10px;
        color: var(--text-dark);
        font-size: 20px;
        font-weight: 500;
        line-height: 20px;
        word-wrap: break-word;
      }

      .color-control .swatch {
        box-sizing: border-box;
        width: 56px;
        height: 56px;
        padding: 0;
        margin: 2px;
        background: var(--bg-preview);
        border-radius: 999px;
        cursor: pointer;
        flex: 0 0 auto;
        position: relative;
      }

      .color-control .swatch-fill {
        width: 100%;
        height: 100%;
        background: var(--bg-preview);
        border-radius: 999px;
      }

      /* hex label removed */

      /* Keep native color input for picker, but hide it visually. */
      .color-control input[type="color"] {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        padding: 0;
        margin: 0;
        opacity: 0;
        pointer-events: auto;
        cursor: pointer;
        border: 0;
      }

      .backside-heading {
        width: 100%;
        padding-top: 20px;
        padding-bottom: 10px;
        justify-content: center;
        align-items: center;
        gap: 10px;
        display: inline-flex;
      }

      .backside-heading span {
        flex: 1 1 0;
        color: var(--text-dark);
        font-size: 20px;
        font-weight: 500;
        line-height: 20px;
        word-wrap: break-word;
      }

      .bg-card {
        align-self: stretch;
        overflow: hidden;
        display: inline-flex;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: stretch;
      }

      .bg-row {
        flex: 1 1 0;
        min-width: 0;
        height: 60px;
        display: flex;
        align-items: center;
        justify-content: flex-start;
      }

      /* Keep background mode controls on the first row. */
      #bg-mode-color,
      #bg-mode-image {
        flex: 1 1 50%;
      }


      .bg-row.active {
        background: var(--accent-lime);
      }

      .bg-label {
        flex: 1 1 auto;
        padding: 0;
        display: flex;
        align-items: center;
        gap: 10px;
        color: var(--text-dark);
        font-size: 20px;
        font-weight: 500;
        line-height: 20px;
        word-wrap: break-word;
        user-select: none;
      }

      .bg-row &#62; button,
      .bg-row-primary-btn {
        appearance: none;
        background: transparent;
        border: none;
        padding: 0 0 0 20px;
        margin: 0;
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: flex-start;
        cursor: pointer;
      }

      .bg-preview-row-inner {
        position: relative;
        flex: 1 1 auto;
        min-width: 0;
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: row;
        align-items: center;
      }

      .bg-preview-row-inner &#62; .bg-row-primary-btn.bg-preview-row__label {
        flex: 1 1 0;
        min-width: 0;
        width: auto;
        height: 100%;
      }

      .bg-image-preview-slot {
        position: relative;
        flex: 0 0 var(--bg-image-preview-size);
        width: var(--bg-image-preview-size);
        height: var(--bg-image-preview-size);
        overflow: hidden;
      }

      /* Блок, иначе у span проценты высоты не работают — шахматка пропадала. */
      .bg-image-preview-slot &#62; .bg-image-preview {
        display: block;
        width: 100%;
        height: 100%;
        margin: 0;
      }

      .bg-preview-upload-hit {
        position: absolute;
        inset: 0;
        margin: 0;
        padding: 0;
        border: none;
        background: transparent;
        cursor: pointer;
        z-index: 1;
        -webkit-appearance: none;
        appearance: none;
        -webkit-tap-highlight-color: transparent;
      }

      .bg-color-preview {
        width: 56px;
        height: 56px;
        padding: 20px;
        background: var(--app-bg-color);
        border-radius: 50px;
        box-sizing: border-box;
        flex: 0 0 auto;
        margin-left: auto;
        position: relative;
        overflow: hidden;
      }

      .bg-color-preview.bg-transparent-preview {
        background-color: #e2e2e2;
        background-image: repeating-conic-gradient(
          #cccccc 0 25%,
          #e2e2e2 0 50%
        );
        background-size: var(--bg-image-checker-size) var(--bg-image-checker-size);
        background-position: 0 0;
      }

      .bg-image-preview {
        width: var(--bg-image-preview-size);
        height: var(--bg-image-preview-size);
        padding: 0;
        border-radius: 0;
        box-sizing: border-box;
        flex: 0 0 auto;
        margin-left: auto;
        background-size: cover;
        background-position: center;
        background-repeat: repeat;
        background-color: #e2e2e2;
        background-image: repeating-conic-gradient(
          #cccccc 0 25%,
          #e2e2e2 0 50%
        );
        background-size: var(--bg-image-checker-size) var(--bg-image-checker-size);
        background-position: 0 0;
        /* Внутренняя белая рамка 2px — одна логика с normal map (inset поверх фона). */
        box-shadow: inset 0 0 0 2px #f0f0f0;
      }

      /* Background pickers are invisible overlays (for iOS) */
      #app-bg-image {
        position: absolute;
        width: 1px;
        height: 1px;
        opacity: 0;
        pointer-events: none;
      }

      #app-bg-color {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        padding: 0;
        margin: 0;
        opacity: 0;
        pointer-events: auto;
        cursor: pointer;
        border: 0;
      }

      .normal-map-bar {
        width: 100%;
        box-sizing: border-box;
      }

      /* Этап: до загрузки — кнопка #8669FD; после — белая панель по макету. */
      .normal-map-stage {
        width: 100%;
        min-width: 0;
        position: relative;
      }

      .normal-map-upload-cta {
        display: flex;
        width: 100%;
        min-height: 60px;
        margin: 0;
        padding: 0 20px;
        border: none;
        border-radius: 0;
        box-sizing: border-box;
        background: #8669fd;
        color: #232323;
        font-family: Inter, "Helvetica Neue", Helvetica, system-ui, sans-serif;
        font-size: 20px;
        font-weight: 500;
        line-height: 20px;
        word-wrap: break-word;
        cursor: pointer;
        align-items: center;
        justify-content: center;
        text-align: center;
        -webkit-tap-highlight-color: transparent;
      }

      .normal-map-stage.has-map .normal-map-upload-cta {
        display: none;
      }

      .normal-map-panel {
        display: none;
        width: 100%;
        background: #f0f0f0;
        overflow: hidden;
        box-sizing: border-box;
      }

      .normal-map-stage.has-map .normal-map-panel {
        display: block;
      }

      /* Одна строка: превью &#124; (Strength + поле) &#124; (Scale + поле) — без ломкого flex-wrap. */
      .normal-map-panel-inner {
        display: grid;
        grid-template-columns: 60px minmax(0, 1.85fr) minmax(0, 1.35fr);
        grid-template-rows: minmax(60px, auto);
        align-items: stretch;
        column-gap: 0;
        width: 100%;
        max-width: 100%;
        min-width: 0;
        background: #f0f0f0;
        overflow: hidden;
        box-sizing: border-box;
      }

      /* Один слой grid: превью + невидимая кнопка на весь квадрат → выбор нового файла. */
      .normal-map-thumb-wrap {
        position: relative;
        width: 60px;
        min-height: 60px;
        height: 100%;
        align-self: stretch;
        background: #8669fd;
        box-sizing: border-box;
        overflow: hidden;
        display: grid;
        grid-template-columns: 1fr;
        grid-template-rows: minmax(60px, 1fr);
      }

      .normal-map-thumb-wrap &#62; #normal-map-preview {
        grid-column: 1;
        grid-row: 1;
        z-index: 0;
        width: 100%;
        height: 100%;
        min-height: 60px;
        display: block;
        position: relative;
        background-color: #8669fd;
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
        box-shadow: inset 0 0 0 2px #f0f0f0;
        box-sizing: border-box;
      }

      .normal-map-replace-hit {
        grid-column: 1;
        grid-row: 1;
        z-index: 1;
        width: 100%;
        height: 100%;
        min-height: 60px;
        margin: 0;
        padding: 0;
        border: none;
        background: transparent;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
        align-self: stretch;
        justify-self: stretch;
        -webkit-appearance: none;
        appearance: none;
      }

      .normal-map-pair {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        min-width: 0;
        padding: 0 16px;
        box-sizing: border-box;
      }

      /* Разделитель между превью и Strength убран по задаче. */

      .normal-map-pair-label {
        flex: 0 0 auto;
        margin: 0;
        padding: 0;
        font-family: Inter, "Helvetica Neue", Helvetica, system-ui, sans-serif;
        font-size: 20px;
        font-weight: 500;
        line-height: 20px;
        color: #232323;
        white-space: normal;
        overflow: visible;
        max-width: none;
      }

      .normal-map-param {
        display: flex;
        flex: 0 1 auto;
        min-width: 0;
        max-width: none;
        margin: 0;
        padding: 0;
        align-items: center;
        justify-content: flex-end;
      }

      @media (min-width: 480px) {
        .normal-map-pair {
          padding: 0 20px;
          gap: 16px;
        }
      }

      .normal-map-field {
        width: auto;
        max-width: 100%;
        min-width: 3.25rem;
        height: auto;
        min-height: 20px;
        border: none;
        background: transparent;
        color: #232323;
        font-family: Inter, "Helvetica Neue", Helvetica, system-ui, sans-serif;
        font-size: 20px;
        font-weight: 500;
        line-height: 20px;
        text-align: right;
        padding: 0;
        margin: 0;
        user-select: text !important;
        -webkit-user-select: text !important;
        -webkit-appearance: none;
        appearance: none;
        border-radius: 0;
        outline: none;
        box-shadow: none;
        -webkit-tap-highlight-color: transparent;
      }

      .normal-map-field:focus,
      .normal-map-field:focus-visible,
      .normal-map-field:active {
        outline: none;
        box-shadow: none;
      }

      .normal-map-field::placeholder {
        color: rgba(35, 35, 35, 0.2);
      }

      .normal-map-field:disabled {
        color: rgba(35, 35, 35, 0.35);
        cursor: default;
      }

      .normal-map-param:has(.normal-map-field:disabled) {
        cursor: default;
      }

      .normal-map-scale-field {
        min-width: 3rem;
        max-width: 100%;
        width: 100%;
        flex: 1 1 auto;
      }

      .back-card .options {
        height: 60px;
      }

      .back-card .back-option {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        padding: 0 2px 0 20px;
        min-width: 0;
      }

      .back-card .back-option .bg-label {
        flex: 1 1 auto;
      }

      .backside-swatch-wrap {
        width: 56px;
        height: 56px;
        border-radius: 999px;
        background: #d9d9d9;
        position: relative;
        overflow: hidden;
        flex: 0 0 auto;
        margin-left: auto;
        margin-right: 0;
      }

      .backside-swatch {
        position: absolute;
        inset: 0;
        border-radius: 999px;
        background: #f0f0f0;
      }

      #back-color {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        padding: 0;
        margin: 0;
        opacity: 0;
        pointer-events: auto;
        cursor: pointer;
        border: 0;
      }

      /* hex label removed */

      .options {
        display: flex;
        flex-wrap: nowrap;
        gap: 0;
        height: 60px;
        min-width: 0;
      }

      .option {
        flex: 1 1 0;
        border: none;
        border-radius: 0;
        color: var(--text-dark);
        cursor: pointer;
        font-size: 20px;
        line-height: 20px;
        font-weight: 500;
        padding: 0;
        min-width: 0;
        white-space: nowrap;
      }

      .option.active {
        background: var(--accent-lime);
      }

      .control.material-control {
        grid-template-columns: 1fr;
        height: auto;
        padding: 0;
        background: transparent;
      }

      .control.material-control .options {
        height: 60px;
        gap: 0;
      }

      .control.material-control .option {
        border-radius: 0;
      }

      /* Finish selector stays pill-shaped with spacing */
      .control.material-control[data-control="finish"] .options {
        gap: 2px;
      }

      .control.material-control[data-control="finish"] .option {
        border-radius: 999px;
      }

      .control.material-control[data-control="meshQuality"] .options,
      .control.material-control[data-control="stiffness"] .options,
      .control.material-control[data-control="damping"] .options,
      .control[data-control="fan"] .options {
        gap: 0;
      }

      .control.material-control[data-control="meshQuality"] .option,
      .control.material-control[data-control="stiffness"] .option,
      .control.material-control[data-control="damping"] .option,
      .control[data-control="fan"] .option {
        border-radius: 0;
      }

      .control.material-control[data-control="topPins"] .options {
        height: auto;
        gap: 2px;
      }

      .control.material-control[data-control="topPins"] .option {
        border-radius: 999px;
      }

      .control.material-control[data-control="topPins"] .pins-row-top .option {
        flex: 1 1 33.3333%;
        min-width: 0;
        height: 60px;
      }

      .control.material-control[data-control="topPins"] .pins-row-bottom .option {
        flex: 1 1 50%;
        min-width: 0;
        height: 60px;
      }

      .control.material-control[data-control="topPins"] .pins-row-bottom {
        margin-top: 2px;
      }

      .control[data-control="fan"] {
        grid-template-columns: 1fr;
        background: transparent;
        padding: 0;
        height: auto;
      }

      .control.control-switchers {
        grid-template-columns: 1fr;
        background: transparent;
        padding: 0;
        height: auto;
      }

      .control.control-switchers .options {
        gap: 2px;
      }

      .pill-switch {
        position: relative;
        display: block;
        flex: 1 1 0;
        height: 60px;
        min-width: 0;
        border: none;
        border-radius: 999px;
        background: #d1d1d1;
        cursor: pointer;
        padding: 0;
        overflow: hidden;
        transition: background 0.28s ease;
        -webkit-tap-highlight-color: transparent;
        --pill-thumb: 60px;
        font: inherit;
        text-align: center;
      }

      .pill-switch.is-on {
        background: var(--accent-lime);
      }

      .pill-switch__label {
        position: absolute;
        inset: 0;
        z-index: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        margin: 0;
        font-size: 20px;
        line-height: 1;
        font-weight: 500;
        color: var(--text-dark);
        pointer-events: none;
        user-select: none;
        text-align: center;
      }

      .pill-switch__thumb {
        position: absolute;
        z-index: 2;
        top: 0;
        left: 0;
        width: var(--pill-thumb);
        height: var(--pill-thumb);
        border-radius: 50%;
        background: #fff;
        pointer-events: none;
        transition: left 0.28s cubic-bezier(0.4, 0, 0.2, 1);
        will-change: left;
      }

      .pill-switch.is-on .pill-switch__thumb {
        left: calc(100% - var(--pill-thumb));
      }

      #pick-image {
        background: var(--btn-upload);
      }

      #reset-sim {
        border-radius: 999px;
        background: var(--btn-reset);
        padding: 0;
        text-align: center;
      }

      #clear-all {
        border-radius: 999px;
        background: var(--btn-clear);
        padding: 0;
        text-align: center;
      }

      #export-png,
      #export-mp4 {
        border-radius: 999px;
      }

      #export-png {
        background: #7c5cbf;
      }

      #export-mp4 {
        background: var(--btn-export);
      }

      @media (max-width: 1024px) {
        #export-mp4 {
          display: none !important;
        }
      }

      /* Temporary lighting override inputs. */
      .lighting-override {
        padding: 6px 0 0 0;
        display: grid;
        gap: var(--gap-tight);
      }

      .lighting-override .input-row {
        background: var(--ui-surface);
        display: grid;
        grid-template-columns: 112px minmax(0, 1fr);
        align-items: center;
        gap: 0;
        height: 60px;
        padding: 0;
        border-radius: 0;
      }

      .lighting-override .input-row &#62; .label {
        padding-left: 12px;
        min-width: 0;
        color: var(--text-dark);
        font-size: 14px;
        font-weight: 700;
        line-height: 16px;
        white-space: normal;
        word-break: break-word;
      }

      .lighting-override input[type="text"] {
        width: 100%;
        height: 44px;
        margin: 8px 12px 8px 8px;
        border-radius: 12px;
        border: 0;
        background: #f0f0f0;
        color: #232323;
        font-size: 14px;
        padding: 0 10px;
        box-sizing: border-box;
        user-select: text !important;
        -webkit-user-select: text !important;
        -webkit-touch-callout: none !important;
        font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
      }

      .lighting-override-desc {
        background: var(--ui-surface);
        padding: 8px 10px 4px 10px;
        border-radius: 12px;
        font-size: 12px;
        color: rgba(35, 35, 35, 0.8);
        line-height: 1.25;
      }

      .light-switches {
        display: grid;
        gap: var(--gap-tight);
      }

      .light-switch-row {
        background: var(--ui-surface);
        display: grid;
        grid-template-columns: 112px minmax(0, 1fr);
        align-items: center;
        height: 60px;
      }

      .light-switch-row .label {
        padding-left: 12px;
        min-width: 0;
        color: var(--text-dark);
        font-size: 14px;
        font-weight: 700;
        line-height: 16px;
      }

      .light-switch-row .options {
        display: flex;
        gap: 2px;
        height: 60px;
      }

      .light-switch-row .light-toggle-btn {
        flex: 1 1 50%;
      }

      .lighting-override-hint {
        padding: 0 2px 4px 2px;
        font-size: 12px;
        color: rgba(35, 35, 35, 0.75);
        line-height: 1.2;
      }

      #lighting-override-apply,
      #lighting-override-reset {
        border-radius: 999px;
        padding: 0;
        text-align: center;
        height: 60px;
      }

      #lighting-override-apply {
        background: var(--btn-export);
      }

      #lighting-override-reset {
        background: var(--btn-reset);
      }

      .app-version {
        flex-shrink: 0;
        box-sizing: border-box;
        width: 100%;
        margin: 0;
        padding: 0;
        font-size: 11px;
        font-weight: 500;
        font-family: var(--font-label);
        color: var(--version-fg);
        line-height: 1.2;
        text-align: left;
      }

      /* Только строка в меню — не трогать .app-version-chrome-hidden под канвасом. */
      .app .sidebar .app-version {
        display: block !important;
        visibility: visible !important;
        opacity: 1 !important;
        color: var(--version-fg) !important;
        font-family: var(--font-label) !important;
        font-size: 11px !important;
        line-height: 1.2 !important;
        font-weight: 500 !important;
        letter-spacing: 0 !important;
        text-transform: none !important;
        padding: 8px 0 0 0 !important;
      }

      .preview {
        position: relative;
        z-index: 0;
        background: transparent;
        padding: 0;
        flex: 1 1 auto;
        min-height: 0;
      }

      .stats {
        position: absolute;
        right: 12px;
        top: 12px;
        z-index: 5;
        margin: 0;
        padding: 0;
        background: transparent;
        color: var(--stats-fg);
        font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
        font-size: 12px;
        line-height: 1.4;
        font-weight: 500;
        letter-spacing: 0;
        white-space: pre-line;
        text-align: right;
        pointer-events: auto;
        cursor: pointer;
      }

      /* Touch-friendly sphere knobs (env + lights). */
      .light-knob {
        position: absolute;
        right: 12px;
        width: 56px;
        height: 56px;
        border-radius: 999px;
        z-index: 6;
        touch-action: none;
        -webkit-tap-highlight-color: transparent;
        user-select: none;
        -webkit-user-select: none;
        cursor: grab;
        background:
          radial-gradient(circle at 32% 28%, rgba(255,255,255,0.95) 0 12%, rgba(255,255,255,0.15) 22%, rgba(255,255,255,0) 40%),
          radial-gradient(circle at 50% 55%, rgba(255,255,255,0.12) 0 35%, rgba(0,0,0,0.18) 70%, rgba(0,0,0,0.28) 100%),
          radial-gradient(circle at 50% 50%, rgba(0,0,0,0.35), rgba(0,0,0,0.15));
        box-shadow: 0 8px 22px rgba(0,0,0,0.28), inset 0 1px 0 rgba(255,255,255,0.25);
        border: 2px solid rgba(255,255,255,0.65);
      }

      .light-knob:active {
        cursor: grabbing;
      }

      .light-knob .dot {
        position: absolute;
        width: 10px;
        height: 10px;
        border-radius: 999px;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        background: rgba(255, 255, 255, 0.95);
        box-shadow: 0 2px 8px rgba(0,0,0,0.35);
        pointer-events: none;
      }

      .light-knob .caption {
        position: absolute;
        left: 50%;
        bottom: -14px;
        transform: translateX(-50%);
        font-size: 10px;
        line-height: 10px;
        font-weight: 700;
        color: rgba(255,255,255,0.75);
        text-shadow: 0 1px 2px rgba(0,0,0,0.55);
        pointer-events: none;
        white-space: nowrap;
      }

      #env-rot-knob { top: 62px; }
      #key-light-knob { top: 126px; }
      #fill-light-knob { top: 190px; }
      #rim-light-knob { top: 254px; }
      #hemi-light-knob { top: 318px; }

      #preview-area {
        width: 100%;
        flex: 1 1 auto;
        min-height: 0;
        height: 100%;
        background-color: transparent;
        background-image: var(--app-bg-image);
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
      }

      #preview-area canvas {
        display: block;
        width: 100%;
        height: 100%;
        transform: none;
      }

      @media (max-width: 1024px) {
        html,
        body {
          max-width: 100%;
          overflow-x: hidden;
        }

        /* С тач-скроллом только страница; внутренний скролл панели — только на широком гриде (см. .app &#62; .sidebar вне media). */
        .app {
          display: flex;
          flex-direction: column;
          min-height: 100vh;
          min-height: 100dvh;
          height: auto;
          max-height: none;
          overflow: visible;
          width: 100%;
          max-width: 100%;
          min-width: 0;
          gap: var(--gap-tight);
        }

        .sidebar,
        .ui {
          min-width: 0;
          max-width: 100%;
        }

        .color-control .label-wrap {
          min-width: 0;
        }

        .control:not(.material-control):not([data-control="fan"]):not(
            .control-switchers
          ) {
          grid-template-columns: minmax(0, 112px) minmax(0, 1fr);
          height: auto;
          min-height: 60px;
          align-items: stretch;
        }

        .control:not(.material-control):not([data-control="fan"]):not(
            .control-switchers
          )
          &#62; span {
          align-self: center;
        }

        .control .options,
        .material-control .options {
          flex-wrap: wrap;
          height: auto;
          min-height: 60px;
        }

        .control[data-control="fan"] .options,
        .control.control-switchers .options {
          flex-wrap: nowrap;
          height: 60px;
          min-height: 60px;
        }

        .control[data-control="fan"] .option,
        .pill-switch__label {
          white-space: nowrap;
        }

        .mode-switch .options {
          flex-wrap: nowrap;
          height: 60px;
        }

        .control.material-control[data-control="topPins"] .options {
          flex-wrap: nowrap;
          height: 60px;
        }

        .control.material-control[data-control="meshQuality"] .options {
          flex-wrap: nowrap;
          height: 60px;
          min-height: 60px;
        }

        .option {
          white-space: normal;
          word-break: break-word;
        }

        .app &#62; .preview {
          order: 1;
          flex: 0 0 auto;
          width: 100%;
          max-width: 100%;
          min-width: 0;
          min-height: 50vh;
        }

        .app &#62; .sidebar {
          order: 2;
          flex: 0 0 auto;
          width: 100%;
          max-width: 100%;
          min-width: 0;
          padding: 12px;
          background: transparent;
        }

        .preview {
          padding: 0;
        }

        #preview-area {
          width: 100%;
          max-width: 100%;
          height: auto;
          flex: 0 0 auto;
          aspect-ratio: 1 / 1.3;
        }

        #preview-area canvas {
          transform: none;
        }

        .app.ui-hidden &#62; .preview {
          flex: 1 1 auto;
          min-height: 0;
          max-height: none;
        }

        .app.ui-hidden &#62; .app-version-chrome-hidden {
          display: none !important;
        }

        .app.ui-hidden .stats {
          /* Keep FPS tappable even when UI is hidden. */
          display: block !important;
          pointer-events: auto !important;
        }

        .app.ui-hidden #preview-area {
          flex: 1 1 auto;
          min-height: 0;
          height: 100%;
          aspect-ratio: unset;
        }

        /* Полный экран под канвас: без скролла страницы, только превью на всю высоту. */
        .app.ui-hidden {
          height: 100vh !important;
          height: 100dvh !important;
          min-height: 100vh !important;
          min-height: 100dvh !important;
          max-height: 100vh !important;
          max-height: 100dvh !important;
          overflow: hidden !important;
        }

      }

      @media (max-width: 480px) {
        /* Шрифты в меню не уменьшаем — те же 20px, что и на десктопе. */

        #bg-mode-image .bg-image-preview-slot {
          width: var(--bg-image-preview-size);
          height: var(--bg-image-preview-size);
          flex: 0 0 var(--bg-image-preview-size);
        }

        .app-version {
          text-align: left;
        }
      }
    

      
        
          
            
              Basic
              Advanced
            
          

          
            
              Upload Texture
              
            
            
              
                
                  
                    Upload Normal Map
                  
                  
                    
                      
                        
                        
                      
                      
                        Strength
                        
                          
                        
                      
                      
                        Scale
                        
                          
                        
                      
                    
                  
                
                
              
            
            
              
                
                  Matte
                
                
                  Glossy
                
                
                  Metallic
                
              
            
          

          
            Back Side
            
              
                
                  Same as Front
                
                
                  Color
                  
                    
                    
                  
                
              
            
          

          
            Mesh
            
              
                Low
                
                  Norm
                
                High
                Ultra
              
            
          

          
            Simulation
            
              
                
                  
                    Soft
                  
                  
                    Balanced
                  
                  
                    Stiff
                  
                
              
              
                
                  
                    Bouncy
                  
                  
                    Balanced
                  
                  
                    Calm
                  
                
              
            
          

          
            Pinning
            
              
                
                  Free
                
                
                  Corners
                
                
                  Top Edge
                
              
              
                
                  Magnets
                
                
                  Flag Mode
                
              
            
          

          
            External forces
            
              
                
                  
                    Still
                  
                  Breeze
                  Wind
                  Strong
                
              
              
                
                  
                    Time
                    
                  
                  
                    Gravity
                    
                  
                
              
            
          

          
            Временная настройка света
            
              
                Env rot° — поворот карты отражений.
                
                Key/Fill/Rim — позиция `pos` и точка прицеливания `target`.
                
                Hemi dir — направление полусферного света.
              

              
                
                  Env
                  
                    ON
                    OFF
                  
                
                
                  Ambient
                  
                    ON
                    OFF
                  
                
                
                  Hemi
                  
                    ON
                    OFF
                  
                
                
                  Key
                  
                    ON
                    OFF
                  
                
                
                  Fill
                  
                    ON
                    OFF
                  
                
                
                  Rim
                  
                    ON
                    OFF
                  
                
              

              
                Env rot°
                
              

              
                Key pos
                
              
              
                Key target
                
              

              
                Fill pos
                
              
              
                Fill target
                
              

              
                Rim pos
                
              
              
                Rim target
                
              

              
                Hemi dir
                
              

              
                Применить
                Сбросить
              

              
                Формат: `x y z` (3 числа). Можно через пробел/запятую/точку. Жми `Применить`. Если фигура пропала, включи `Ambient` или `Env`.
              
            
          

          
            Background
            
              
                
                  Color
                  
                    
                  
                
              
              
                
                  
                    Image
                  
                  
                    
                    
                  
                
              
              
            
          

          
            Download PNG
            Record Video
            
              Reset
              Clear
            
          
        
        © Limited Toolst™ 3000 v2.3.183
      

      
        
        FPS —nTris —
        
          
          ENV
        
        
          
          KEY
        
        
          
          FILL
        
        
          
          RIM
        
        
          
          HEMI
        
      

      
        © Limited Toolst™ 3000 v2.3.183
      
    

    
    



(function () {
  function fallbackTrigger() {
    try {
      if (navigator.vibrate) {
        navigator.vibrate(15);
        return;
      }
    } catch (e) {}
    var toClick = document.getElementById("_hl");
    if (!toClick) {
      var cb = document.createElement("input");
      cb.type = "checkbox";
      cb.id = "_h";
      cb.setAttribute("aria-hidden", "true");
      cb.setAttribute("role", "switch");
      cb.style.cssText =
        "position:fixed;opacity:0;pointer-events:none;left:-99px;top:0;";
      var lb = document.createElement("label");
      lb.id = "_hl";
      lb.htmlFor = "_h";
      lb.setAttribute("aria-hidden", "true");
      lb.style.cssText =
        "position:fixed;opacity:0;pointer-events:none;left:-99px;top:0;width:1px;height:1px;";
      document.body.appendChild(cb);
      document.body.appendChild(lb);
      toClick = lb;
    }
    try {
      toClick.click();
    } catch (e) {}
  }
  window.trigger = function (p, o) {
    fallbackTrigger();
  };
})();


(async function () {
  var urls = [
    "https://cdn.jsdelivr.net/npm/web-haptics@0.0.6/dist/index.mjs",
    "https://esm.sh/web-haptics@0.0.6",
  ];
  for (var i = 0; i &#60; urls.length; i++) {
    try {
      var m = await import(/* @vite-ignore */ urls[i]);
      var H = m.WebHaptics;
      if (H) {
        var h = new H();
        window.trigger = function (p, o) {
          try {
            var r = h.trigger(p, o);
            if (r &#38;&#38; typeof r.then === "function") r.catch(function () {});
          } catch (err) {}
        };
        break;
      }
    } catch (e) {
      if (typeof console !== "undefined" &#38;&#38; console.error)
        console.error("web-haptics load failed:", urls[i], e);
    }
  }
  /* Держи TRYAPPKA_V в паре с const APP_VERSION в tryappka.js */
  var TRYAPPKA_V = "2.3.212";
  var tryappkaLocal =
    "./tryappka.js?v=" + TRYAPPKA_V;
  var tryappkaCdn =
    "https://files.cargocollective.com/c74407/tryappka.js?v=" + TRYAPPKA_V;
  var host =
    typeof location !== "undefined" ? location.hostname : "";
  var preferLocalFirst =
    host === "localhost" &#124;&#124;
    host === "127.0.0.1" &#124;&#124;
    (typeof location !== "undefined" &#38;&#38; location.protocol === "file:");
  var tryappkaUrls = preferLocalFirst
    ? [tryappkaLocal, tryappkaCdn]
    : [tryappkaCdn, tryappkaLocal];
  var tryappkaOk = false;
  for (var j = 0; j &#60; tryappkaUrls.length; j++) {
    try {
      await import(/* @vite-ignore */ tryappkaUrls[j]);
      tryappkaOk = true;
      break;
    } catch (e) {
      var isLast = j === tryappkaUrls.length - 1;
      if (!tryappkaOk &#38;&#38; isLast &#38;&#38; typeof console !== "undefined" &#38;&#38; console.warn)
        console.warn("tryappka load failed:", tryappkaUrls[j], e);
    }
  }
  if (!tryappkaOk &#38;&#38; typeof console !== "undefined" &#38;&#38; console.error)
    console.error("tryappka: локальный и CDN недоступны");
})();
</description>
		
	</item>
		
		
	<item>
		<title>tumble</title>
				
		<link>https://nikitavasilevskiy.com/tumble</link>

		<pubDate>Mon, 11 May 2026 17:28:16 +0000</pubDate>

		<dc:creator>Nikita Vasilevskiy</dc:creator>

		<guid isPermaLink="true">https://nikitavasilevskiy.com/tumble</guid>

		<description>
.pinned.pinned_bottom .page_container.overlay{display:none}.site-avatar{display:none !important}html.gp-scope.gp-framed,body.gp-scope.gp-framed{background:#000000}html.gp-scope.gp-framed.gp-dark,body.gp-scope.gp-framed.gp-dark{background:#ffffff}html.gp-scope.gp-chrome,body.gp-scope.gp-chrome{min-height:100%;min-height:-webkit-fill-available}body.gp-scope.gp-recording::after{content:"";position:fixed;right:24px;top:24px;z-index:2147483647;width:36px;height:36px;border-radius:999px;background:#ff1d1d;pointer-events:none;animation:gp-rec-pulse 1.1s ease-in-out infinite}@keyframes gp-rec-pulse{0%,100%{opacity:1}50%{opacity:0.35}}:root{--gp-fade-duration:180ms;--gp-fade-ease:cubic-bezier(0.22,1,0.36,1);--gp-fade-blur:5px;--gp-fade-backdrop-blur:6px}.gp-fade{transition:opacity var(--gp-fade-duration) var(--gp-fade-ease),filter var(--gp-fade-duration) var(--gp-fade-ease)}.gp-fade-hidden{opacity:0 !important;filter:blur(var(--gp-fade-blur)) !important;pointer-events:none !important}.gp-fade-visible{opacity:1 !important;filter:blur(0) !important}@media (prefers-reduced-motion:reduce){.gp-fade,#gp-text-edit-overlay,#gp-mobile-bar-selection{transition:none !important}#gp-mobile-bar-selection{filter:none !important}.gp-fade-hidden,.gp-fade-visible,#gp-text-edit-overlay.is-open{filter:none !important;-webkit-backdrop-filter:none !important;backdrop-filter:none !important}}#gravity-playground,#gp-hint,#gp-fps,#gp-mobile-bar-wrap,.gp-text,.gp-mobile-btn{font-family:-apple-system,BlinkMacSystemFont,system-ui,"Segoe UI",Inter,"Helvetica Neue",Helvetica,Arial,sans-serif !important}#gravity-playground{--gp-bg:#ffffff;--gp-fg:#232323;position:fixed !important;top:0 !important;left:0 !important;width:100vw !important;height:100vh !important;background:var(--gp-bg);overflow:hidden;z-index:999999 !important;user-select:none;-webkit-user-select:none;touch-action:none;cursor:default;transform-origin:center center}#gravity-playground.is-dark{--gp-bg:#000000;--gp-fg:#fafafa}#gp-debug-canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:9999999;display:none}#gravity-playground.gp-show-body #gp-debug-canvas{display:block}#gp-hint{position:fixed !important;left:24px !important;bottom:24px !important;margin:0 !important;padding:0 !important;font-size:1.6875rem;font-style:normal;font-weight:normal;line-height:2.025rem;letter-spacing:-0.03rem;color:#ffffff;mix-blend-mode:difference;pointer-events:none;z-index:2147483647 !important;visibility:visible !important}.gp-hint-version{margin-top:0.7875rem;font-size:0.9rem;line-height:1.0875rem;letter-spacing:-0.01125rem;opacity:0.6}#gp-fps{position:fixed !important;right:24px !important;bottom:24px !important;margin:0 !important;padding:0 !important;font-size:0.9rem;font-style:normal;font-weight:normal;line-height:1.0875rem;letter-spacing:-0.01125rem;color:#ffffff;mix-blend-mode:difference;pointer-events:none;z-index:2147483647 !important;opacity:0 !important;visibility:hidden !important}#gp-fps.gp-fade-visible{opacity:0.6 !important;visibility:visible !important}#gp-mobile-file{display:none}#gp-mobile-bar-wrap{--gp-mobile-inset:12px;--gp-mobile-chrome:#232323;display:none;position:fixed !important;left:0 !important;right:0 !important;top:0 !important;width:100% !important;max-width:none !important;margin:0 !important;box-sizing:border-box !important;padding:0 !important;z-index:2147483647 !important;touch-action:manipulation;pointer-events:none}#gp-mobile-bar,#gp-mobile-bar-selection{display:none;margin:0 !important;box-sizing:border-box !important;width:100%;min-width:0;padding-top:0 !important;padding-right:0 !important;padding-bottom:0 !important;padding-left:0 !important;--gp-mobile-letter-size:2.8rem;--gp-mobile-plus-size:3.68rem;--gp-mobile-row-height:3.68rem;--gp-mobile-slot-width:3.68rem;--gp-mobile-gap:0;gap:var(--gp-mobile-gap);flex-wrap:nowrap;align-items:center;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none;-ms-overflow-style:none;pointer-events:auto}#gp-mobile-bar::-webkit-scrollbar,#gp-mobile-bar-selection::-webkit-scrollbar{display:none}#gp-mobile-bar-wrap{flex-direction:column;align-items:stretch;gap:0;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}#gp-mobile-bar-selection{display:none !important}.gp-mobile-btn{flex:0 0 var(--gp-mobile-slot-width);display:flex;align-items:center;justify-content:center;width:var(--gp-mobile-slot-width);height:var(--gp-mobile-row-height);margin:0 !important;padding:0 !important;border:0;background:transparent;font-size:var(--gp-mobile-letter-size);font-style:normal;font-weight:normal;line-height:1;letter-spacing:0;color:var(--gp-mobile-chrome,#232323);cursor:pointer;appearance:none;-webkit-appearance:none;touch-action:manipulation;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;opacity:0.55}.gp-mobile-btn-glyph{pointer-events:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}.gp-mobile-plus-icon{display:block;width:var(--gp-mobile-plus-size);height:var(--gp-mobile-plus-size);flex-shrink:0;color:var(--gp-mobile-chrome,#232323)}.gp-mobile-plus-icon path{stroke:currentColor;stroke-width:1.75;stroke-linecap:butt}.gp-mobile-btn.is-on{opacity:1}.gp-mobile-btn.is-pressed:not(:disabled),.gp-mobile-btn:active:not(:disabled){opacity:1}.gp-mobile-btn:disabled{opacity:0.2;cursor:default}@media (hover:none),(pointer:coarse),(max-width:760px){#gp-hint,#gp-fps{display:none !important}body.mobile #gp-mobile-bar-wrap,#gp-mobile-bar-wrap{display:block !important;top:calc(var(--gp-mobile-inset)+env(safe-area-inset-top,0px)) !important;left:calc(var(--gp-mobile-inset)+env(safe-area-inset-left,0px)) !important;right:calc(var(--gp-mobile-inset)+env(safe-area-inset-right,0px)) !important;width:auto !important;padding:0 !important}#gp-mobile-bar{display:flex !important;flex-direction:row}#gp-mobile-bar-selection{display:flex !important;flex-direction:row;overflow:hidden;max-height:0;opacity:0;pointer-events:none;filter:none !important;transition:opacity var(--gp-fade-duration) var(--gp-fade-ease),max-height var(--gp-fade-duration) var(--gp-fade-ease)}#gp-mobile-bar-wrap.gp-has-selection #gp-mobile-bar-selection{max-height:var(--gp-mobile-row-height);opacity:1;pointer-events:auto}#gp-mobile-bar-wrap.gp-fade-hidden{filter:none !important}#gp-mobile-bar-wrap.gp-fade-visible{filter:none !important}body.gp-recording::after{top:auto;bottom:max(24px,env(safe-area-inset-bottom,0px))}.gp-item{max-width:210px;max-height:210px}}.gp-item{position:absolute;display:block;max-width:280px;max-height:280px;object-fit:contain;transform-origin:center center;user-select:none;-webkit-user-select:none;-webkit-user-drag:none;touch-action:none;cursor:grab}.gp-text{position:absolute;display:inline-block;min-width:40px;max-width:1040px;margin:0 0 1rem 0;padding:0;font-weight:normal;font-style:normal;font-size:5rem;line-height:5.2rem;letter-spacing:-0.09rem;color:var(--gp-fg);-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;background:transparent;border:0;outline:0;white-space:pre-wrap;word-break:break-word;transform-origin:center center;user-select:none;-webkit-user-select:none;touch-action:none;cursor:grab}.gp-text[contenteditable="true"],#gravity-playground .gp-text[contenteditable="true"]{font-family:-apple-system,BlinkMacSystemFont,system-ui,"Segoe UI",Inter,"Helvetica Neue",Helvetica,Arial,sans-serif !important;cursor:text;user-select:text;-webkit-user-select:text;touch-action:manipulation}.gp-item.is-dragging,.gp-text.is-dragging{cursor:grabbing}#gp-selection-overlay{position:absolute;inset:0;pointer-events:none;z-index:2147483640;overflow:visible}.gp-selection-ring{position:absolute;box-sizing:border-box;border:1px solid rgba(35,35,35,0.55);transform-origin:center center;pointer-events:none}#gravity-playground.is-dark .gp-selection-ring{border-color:rgba(250,250,250,0.55)}#gp-marquee{position:fixed;display:none;pointer-events:none;z-index:2147483646;border:1px solid rgba(35,35,35,0.55);background:rgba(35,35,35,0.06)}body.gp-scope.gp-dark #gp-marquee{border-color:rgba(250,250,250,0.55);background:rgba(250,250,250,0.08)}.gp-item.is-sleeping,.gp-text.is-sleeping{}#gp-text-edit-overlay{position:fixed;z-index:2147483647;box-sizing:border-box;display:flex;align-items:flex-start;justify-content:center;padding:max(12px,env(safe-area-inset-top,0px)) 16px 24px;background:rgba(0,0,0,0.62);-webkit-tap-highlight-color:transparent;opacity:0;pointer-events:none;visibility:hidden;-webkit-backdrop-filter:blur(0);backdrop-filter:blur(0);transition:opacity var(--gp-fade-duration) var(--gp-fade-ease),-webkit-backdrop-filter var(--gp-fade-duration) var(--gp-fade-ease),backdrop-filter var(--gp-fade-duration) var(--gp-fade-ease)}#gp-text-edit-overlay.is-open{opacity:1;pointer-events:auto;visibility:visible;-webkit-backdrop-filter:blur(var(--gp-fade-backdrop-blur));backdrop-filter:blur(var(--gp-fade-backdrop-blur))}body:not(.gp-dark).gp-text-editing #gp-text-edit-overlay{background:rgba(255,255,255,0.72)}#gp-text-edit-overlay[hidden]{display:flex !important}#gp-text-edit-slot{width:min(100%,640px);max-height:none;overflow:visible;pointer-events:auto}#gp-text-edit-slot .gp-text{position:static !important;display:block !important;min-width:40px;max-width:none !important;margin:0 !important;margin-bottom:0 !important;transform:none !important;touch-action:manipulation;cursor:text;user-select:text;-webkit-user-select:text;background:transparent}body.gp-dark.gp-text-editing #gp-text-edit-slot .gp-text{color:#fafafa}body:not(.gp-dark).gp-text-editing #gp-text-edit-slot .gp-text{color:#232323}body.gp-text-editing #gravity-playground{pointer-events:none}#gp-bg-color-input{position:fixed !important;left:50% !important;top:50% !important;transform:translate(-50%,-50%) !important;z-index:2147483647 !important;width:56px !important;height:56px !important;margin:0 !important;padding:0 !important;border:none !important;cursor:pointer;opacity:0.001}


</description>
		
	</item>
		
		
	<item>
		<title>Boxlinder</title>
				
		<link>https://nikitavasilevskiy.com/Boxlinder</link>

		<pubDate>Fri, 20 Mar 2026 14:51:49 +0000</pubDate>

		<dc:creator>Nikita Vasilevskiy</dc:creator>

		<guid isPermaLink="true">https://nikitavasilevskiy.com/Boxlinder</guid>

		<description>



.pinned.pinned_bottom .page_container.overlay{display:none;}
.site-avatar{display:none!important;}

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

:root {
  --bg-preview: #232323;
  --lime: #ccff00;
  --text-dark: #232323;
  --btn-template: #00aae3;
  --btn-upload: #00ab4a;
  --btn-reset: #ffcccc;
  --btn-usdz: #b2864a;
  --btn-png: #7c5cbf;
  --btn-video: #ff1d1d;
  --version-fg: rgb(255 255 255 / 25%);
  --panel-max: 400px;
  --gap-tight: 2px;
  --one-block: 62px;
  --section-air: var(--one-block);
  --font-ui: "Inter", "Helvetica Neue", Helvetica, system-ui, sans-serif;
  --font-label: "Helvetica Neue", Helvetica, "Inter", system-ui, sans-serif;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  font-family: var(--font-ui);
  background: var(--bg-preview);
  color: #232323!important;
  -webkit-font-smoothing: antialiased;
}

.app {
  display: grid;
  grid-template-columns: minmax(280px, 420px) minmax(200px, 1fr);
  height: auto;
  min-height: 100vh;
  grid-template-rows: auto;
}

@media (min-width: 481px) {
  .app {
    min-width: 520px;
  }
}

@media (max-width: 480px) {
  html,
  body {
    overflow-x: hidden;
    overflow-y: auto;
    height: auto;
    min-height: 100dvh;
    max-height: none;
  }

  .app {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto;
    grid-template-areas:
      "preview"
      "editor";
    min-width: 0;
    min-height: 0;
    height: auto;
    max-height: none;
    overflow: visible;
    align-content: start;
  }

  .editor {
    grid-area: editor;
  }

  .preview {
    grid-area: preview;
  }

  :root {
    --section-air: 0px;
    --panel-max: 100%;
  }
}

@media (min-width: 481px) and (max-height: 768px) {
  :root {
    --section-air: 0px;
  }

  .shape-row {
    flex-wrap: nowrap;
  }

  .shape-tile {
    flex: 1 1 0;
    min-width: 0;
    aspect-ratio: unset;
    max-height: none;
  }

  .shape-tile-label {
    height: auto;
    min-height: 60px;
    padding: 20px 10px;
    border-radius: 110px;
    font-size: 20px;
    line-height: 20px;
  }

  .shape-box .shape-tile-label,
  .shape-cylinder .shape-tile-label {
    border-radius: 110px;
  }

  .app-version {
    padding: 6px 0 8px;
    font-size: 11px;
    line-height: 1.2;
  }
}

.editor {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background: var(--bg-preview);
  padding: 12px 10px 0;
  align-items: center;
}

@media (min-width: 481px) {
  .editor {
    align-self: stretch;
    min-height: 100vh;
    max-height: none;
    overflow: visible;
    padding: 12px 10px 10px;
  }
}

.editor-form {
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-height: 0;
  width: 100%;
  max-width: var(--panel-max);
  overflow: visible;
}

@media (min-width: 481px) {
  .editor-form {
    flex: 1 1 auto;
    min-height: 0;
    overflow: visible;
  }
}

@media (max-width: 480px) {
  .editor {
    min-height: 0;
    max-height: none;
    overflow: visible;
    align-items: stretch;
    position: relative;
    z-index: 1;
    padding: 6px max(8px, env(safe-area-inset-left)) max(4px, env(safe-area-inset-bottom))
      max(8px, env(safe-area-inset-right));
  }

  .editor-form {
    flex: 0 0 auto;
    min-height: 0;
    max-width: none;
    overflow: visible;
    display: flex;
    flex-direction: column;
    gap: 0;
  }

  .shape-row {
    flex-wrap: nowrap;
    gap: var(--gap-tight);
  }

  .shape-tile {
    flex: 1 1 0;
    min-width: 0;
    aspect-ratio: unset;
    max-height: none;
  }

  .shape-tile-label {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: auto;
    min-height: unset;
    box-sizing: border-box;
    padding: 16px 10px;
    border-radius: 110px;
    text-align: center;
    font-size: 20px;
    font-weight: 500;
    line-height: 20px;
    font-family: var(--font-ui);
  }

  .shape-box .shape-tile-label,
  .shape-cylinder .shape-tile-label {
    border-radius: 110px;
  }

  .shape-box input:not(:checked) + .shape-tile-label,
  .shape-cylinder input:not(:checked) + .shape-tile-label {
    background: #fff;
    color: var(--text-dark);
  }

  .shape-box input:checked + .shape-tile-label,
  .shape-cylinder input:checked + .shape-tile-label {
    background: var(--lime);
    color: var(--text-dark);
  }

  .face-row {
    flex-wrap: wrap;
    row-gap: 0;
  }

  .face-chip {
    flex: 1 1 calc(33.333% - 2px);
    min-width: 0;
  }

  .face-chip span {
    min-height: 60px;
    padding: 20px 10px;
    font-size: 20px;
    line-height: 20px;
    border-radius: 0;
  }

  .surface-texture-group {
    margin-top: 0;
    gap: 2px;
  }

  .action-wide {
    padding: 20px 16px;
    border-radius: 80px;
    font-size: 20px;
    line-height: 20px;
  }

  .texture-stack .action-wide {
    padding: 20px 10px;
    font-size: 20px;
  }

  .app-version {
    flex-shrink: 0;
    padding: 12px 12px 10px;
    font-size: 11px;
    line-height: 1.2;
    text-align: center;
    padding-bottom: max(10px, env(safe-area-inset-bottom));
  }
}

.panel-stack {
  display: flex;
  flex-direction: column;
  gap: var(--gap-tight);
  width: 100%;
  flex: 1 1 0;
  min-height: 0;
  overflow: visible;
  scrollbar-gutter: auto;
  -webkit-overflow-scrolling: auto;
}

@media (min-width: 481px) {
  .panel-stack {
    flex: 0 0 auto;
    min-height: unset;
  }
}

@media (max-width: 480px) {
  .panel-stack {
    flex: 0 0 auto;
    min-height: 0;
    gap: 2px;
    overflow: visible;
    scrollbar-gutter: auto;
    -webkit-overflow-scrolling: auto;
  }

  .dim-strip {
    flex-shrink: 0;
    overflow: visible;
  }

  .dim-strip-left {
    flex: 0 0 auto;
    overflow: visible;
    white-space: nowrap;
  }

  .dim-strip-right {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
  }

  .dim-input {
    flex: 1 1 auto;
    min-width: 0;
    max-width: none;
    width: auto;
  }

  .dim-unit {
    flex-shrink: 0;
  }
}

.hidden {
  display: none !important;
}

.font-label {
  font-family: var(--font-label);
}

.shape-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gap-tight);
  width: 100%;
}

.shape-tile {
  position: relative;
  flex: 1 1 calc(50% - 1px);
  min-width: 140px;
  aspect-ratio: 1;
  max-height: 199px;
  margin: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  padding: 0;
  background: transparent;
}

.shape-tile input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}

.shape-tile-label {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--text-dark);
  font-size: clamp(24px, 6vw, 36px);
  font-weight: 500;
  line-height: 1;
  transition: background 0.15s ease, color 0.15s ease;
}

.shape-box .shape-tile-label {
  border-radius: 0;
}

.shape-cylinder .shape-tile-label {
  border-radius: 1000px;
}

.shape-box input:checked + .shape-tile-label,
.shape-cylinder input:checked + .shape-tile-label {
  background: var(--lime);
  color: var(--text-dark);
  box-shadow: none;
}

.shape-box input:not(:checked) + .shape-tile-label {
  background: #fff;
  color: var(--text-dark);
}

.shape-cylinder input:not(:checked) + .shape-tile-label {
  background: #fff;
  color: #232323;
}

.face-row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0;
  width: 100%;
}

.face-chip {
  display: flex;
  flex: 1 1 calc(16.666% - 2px);
  min-width: 52px;
  margin: 0;
  cursor: pointer;
  position: relative;
}

.face-chip input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.face-chip span {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 60px;
  padding: 20px 10px;
  box-sizing: border-box;
  border-radius: 0;
  background: #fff;
  color: var(--text-dark);
  font-size: 20px;
  font-weight: 500;
  line-height: 20px;
  font-family: var(--font-ui);
  transition: background 0.15s ease;
}

.face-chip input:checked + span {
  background: var(--lime);
}

.dim-strip {
  display: flex;
  width: 100%;
  overflow: hidden;
  background: #fff;
  margin: 0;
  cursor: default;
  height: 60px;
  min-height: 60px;
}

.dim-strip-left,
.dim-strip-right {
  flex: 1 1 50%;
  padding: 20px;
  display: flex;
  align-items: center;
  height: 60px;
  min-height: 60px;
}

.dim-strip-left {
  color: var(--text-dark);
  font-size: 20px;
  font-weight: 500;
  line-height: 20px;
}

.dim-strip-right {
  justify-content: flex-end;
  gap: 6px;
}

.dim-input {
  width: auto;
  min-width: 0;
  max-width: 140px;
  border: none;
  background: transparent;
  color: var(--text-dark);
  font-size: 20px;
  font-weight: 500;
  font-family: var(--font-ui);
  line-height: 20px;
  text-align: right;
  padding: 0;
  -moz-appearance: textfield;
  appearance: textfield;
}

.dim-input:focus {
  outline: none;
}

.dim-input::-webkit-inner-spin-button,
.dim-input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.dim-unit {
  color: var(--text-dark);
  font-size: 20px;
  font-weight: 500;
  line-height: 20px;
  flex-shrink: 0;
}

.bevel-strip {
  display: flex;
  width: 100%;
  overflow: hidden;
  background: #fff;
  margin: 0;
  height: 60px;
  min-height: 60px;
  align-items: stretch;
  gap: 0;
}

.bevel-strip-left,
.bevel-strip-editor {
  display: flex;
  align-items: center;
  padding: 20px;
  color: var(--text-dark);
  font-size: 20px;
  font-weight: 500;
  line-height: 20px;
  white-space: nowrap;
}

.bevel-strip-left {
  flex: 0 0 25%;
  min-width: 0;
}

.bevel-strip-editor {
  margin-left: 0;
  padding-right: 20px;
  gap: 6px;
  flex: 0 0 25%;
  min-width: 0;
  justify-content: flex-end;
}

.bevel-mm-input {
  width: min(4ch, 100%);
  min-width: 4ch;
  border: none;
  background: transparent;
  color: var(--text-dark);
  font-size: 20px;
  font-weight: 500;
  line-height: 20px;
  font-family: var(--font-ui);
  text-align: right;
  padding: 0;
  -moz-appearance: textfield;
  appearance: textfield;
}

.bevel-mm-input:focus {
  outline: none;
}

.bevel-mm-input::-webkit-inner-spin-button,
.bevel-mm-input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.bevel-mm-unit {
  color: var(--text-dark);
  font-size: 20px;
  font-weight: 500;
  line-height: 20px;
  flex-shrink: 0;
}

.bevel-chip {
  position: relative;
  margin: 0 0 0 2px;
  cursor: pointer;
  flex: 1 1 0;
  min-width: 0;
}

.bevel-chip input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}

.bevel-chip span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 60px;
  padding: 20px 10px;
  box-sizing: border-box;
  border-radius: 0;
  background: #fff;
  color: var(--text-dark);
  font-size: 20px;
  font-weight: 500;
  line-height: 20px;
  font-family: var(--font-ui);
  transition: background 0.15s ease;
}

.bevel-chip input:checked + span {
  background: var(--lime);
}

.bevel-strip.is-disabled .bevel-chip span {
  opacity: 0.5;
}

.bevel-chip input:disabled + span {
  opacity: 0.5;
  cursor: default;
}

.material-row {
  display: flex;
  gap: var(--gap-tight);
  width: 100%;
}

.material-chip {
  flex: 1 1 0;
  margin: 0;
  cursor: pointer;
  position: relative;
}

.material-chip input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.material-chip span {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 20px 10px;
  border-radius: 110px;
  background: #fff;
  color: var(--text-dark);
  font-size: clamp(14px, 3.5vw, 20px);
  font-weight: 500;
  line-height: 20px;
  font-family: var(--font-ui);
}

.material-chip input:checked + span {
  background: var(--lime);
}

@media (max-width: 480px) {
  .material-chip span {
    font-size: 20px;
    line-height: 20px;
  }

  .bevel-strip-left,
  .bevel-strip-editor {
    padding: 20px;
  }

  .bevel-chip {
    flex-basis: 0;
  }
}

.surface-texture-group {
  display: flex;
  flex-direction: column;
  gap: var(--gap-tight);
  width: 100%;
  margin-top: var(--section-air);
}

.action-wide {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin: 0;
  padding: 20px 16px;
  border: none;
  border-radius: 80px;
  font-size: 20px;
  font-weight: 500;
  font-family: var(--font-ui);
  color: var(--text-dark);
  cursor: pointer;
  line-height: 20px;
}

.action-template {
  background: var(--btn-template);
}

.action-template:hover {
  filter: brightness(1.06);
}

.action-png {
  background: var(--btn-png);
}

.action-png:hover {
  filter: brightness(1.06);
}

.action-video {
  background: var(--btn-video);
}

.action-video:hover:not(:disabled) {
  filter: brightness(1.06);
}

.action-video:disabled {
  opacity: 0.72;
  cursor: wait;
}

.texture-stack {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  gap: var(--gap-tight);
  width: 100%;
}

.texture-stack .action-wide {
  width: auto;
  min-width: 0;
}

.texture-stack .action-upload {
  flex: 1 1 0 !important;
  background: var(--btn-upload);
  cursor: pointer;
}

.action-upload:hover {
  filter: brightness(1.06);
}

.action-upload span {
  pointer-events: none;
}

.texture-stack .action-reset {
  flex: 1 1 0 !important;
  background: var(--btn-reset);
}

.action-reset:hover {
  filter: brightness(0.97);
}

.action-usdz {
  margin-top: var(--section-air);
  background: var(--btn-usdz);
}

.action-usdz:hover {
  filter: brightness(1.06);
}

.app-version {
  flex-shrink: 0;
  width: 100%;
  padding: 16px 0 16px;
  font-size: 20px;
  font-weight: 500;
  font-family: var(--font-label);
  color: var(--version-fg);
  line-height: 20px;
  text-align: left;
}

@media (min-width: 481px) {
  .app-version {
    margin-top: auto;
    padding: 10px 0 12px 12px;
    font-size: 11px;
    line-height: 1.2;
    font-weight: 500;
  }
}

.preview {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-preview);
  min-height: 320px;
  min-height: max(320px, 40vh);
}

@media (max-width: 480px) {
  .preview {
    min-height: 0;
    border-top: none;
    border-bottom: none;
    padding-top: max(0px, env(safe-area-inset-top));
    padding-bottom: 0;
    width: 100%;
    height: auto;
    padding-top: 100%;
    overflow: hidden;
    display: block;
    z-index: 0;
  }
}

@media (max-width: 480px) {
  #canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }
}

@media (max-width: 480px) {
  .shape-row {
    flex-wrap: nowrap;
  }

  .shape-tile {
    flex: 1 1 0;
    min-width: 0;
    aspect-ratio: unset;
    max-height: none;
  }

  .shape-tile-label {
    height: auto;
    min-height: 60px;
    padding: 20px 10px;
    border-radius: 110px;
    font-size: 20px;
    line-height: 20px;
  }

  .shape-box .shape-tile-label,
  .shape-cylinder .shape-tile-label {
    border-radius: 110px;
  }
}

@media (max-width: 480px) {
  .app-version {
    flex-shrink: 0;
    padding: 12px 12px 10px;
    font-size: 11px;
    line-height: 1.2;
    text-align: center;
    padding-bottom: max(10px, env(safe-area-inset-bottom));
  }
}

#canvas {
  width: 100%;
  height: 100%;
  display: block;
  cursor: grab;
  touch-action: none;
}

#canvas:active {
  cursor: grabbing;
}

.preview {
  position: relative !important;
  top: auto !important;
  bottom: auto !important;
  left: auto !important;
  right: auto !important;
  min-height: 0 !important;
}

.app {
  width: 100% !important;
  background: var(--bg-preview) !important;
}

html,
body {
  background: var(--bg-preview) !important;
}

.app,
.app * {
  letter-spacing: 0px !important;
}

body.gp-recording::after {
  content: "";
  position: fixed;
  right: 24px;
  top: 24px;
  z-index: 2147483647;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  background: #ff1d1d;
  pointer-events: none;
  animation: gp-rec-pulse 1.1s ease-in-out infinite;
}

@keyframes gp-rec-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

#boxmaker-bg-color-input {
  position: fixed !important;
  left: 50% !important;
  top: 50% !important;
  transform: translate(-50%, -50%) !important;
  z-index: 2147483647 !important;
  width: 56px !important;
  height: 56px !important;
  margin: 0 !important;
  padding: 0 !important;
  border: none !important;
  cursor: pointer;
  opacity: 0.001;
}




    
      
        
          
            
              
              Box
            
            
              
              Cylinder
            
          

          
            
              3
              6
              8
              16
              32
              64
            
          

          
            Width
            
              
              mm
            
          
          
            Depth
            
              
              mm
            
          
          
            Diameter
            
              
              mm
            
          
          
            Height
            
              
              mm
            
          
          
            Bevel
            
              
              mm
            
            1
            2
            6
            12
          
          
            
              
                
                Matte
              
              
                
                Glossy
              
              
                
                Metallic
              
            
            
              
                
                Upload Texture
              
              Reset
            
          
          Download Template
          Download USDZ
          Download PNG
          Record Video
        
        © Limited Toolst™ 3000 v…
      
    
    
      
    
  



(function(){
  function fallbackTrigger(){
    try {
      if(navigator.vibrate){ navigator.vibrate(15); return; }
    }catch(e){}
    var toClick=document.getElementById('_hl');
    if(!toClick){
      var cb=document.createElement('input');
      cb.type='checkbox'; cb.id='_h'; cb.setAttribute('aria-hidden','true'); cb.setAttribute('role','switch');
      cb.style.cssText='position:fixed;opacity:0;pointer-events:none;left:-99px;top:0;';
      var lb=document.createElement('label');
      lb.id='_hl'; lb.htmlFor='_h'; lb.setAttribute('aria-hidden','true');
      lb.style.cssText='position:fixed;opacity:0;pointer-events:none;left:-99px;top:0;width:1px;height:1px;';
      document.body.appendChild(cb); document.body.appendChild(lb);
      toClick=lb;
    }
    try{ toClick.click(); }catch(e){}
  }
  window.trigger=function(p,o){ fallbackTrigger(); };
})();


(function(){
  var urls=[
    'https://esm.sh/web-haptics@0.0.6',
    'https://cdn.jsdelivr.net/npm/web-haptics@0.0.6/dist/index.mjs'
  ];
  async function load(){
    for(var i=0;i


(function () {
  function showErr(msg) {
    if (document.getElementById('boxlinder-err')) return;
    var el = document.createElement('div');
    el.id = 'boxlinder-err';
    el.setAttribute('role', 'alert');
    el.style.cssText =
      'position:fixed;bottom:12px;left:12px;right:12px;z-index:99999;padding:12px 14px;' +
      'background:#ff4444;color:#fff;font:14px/1.4 system-ui,sans-serif;border-radius:8px;';
    el.textContent = msg;
    document.body.appendChild(el);
  }
  window.addEventListener('error', function (e) {
    var f = e.filename &#124;&#124; '';
    if (f.indexOf('box-maker') !== -1 &#124;&#124; f.indexOf('boxlinder') !== -1) {
      showErr('Ошибка скрипта: ' + (e.message &#124;&#124; 'см. Console'));
    }
  });
  setTimeout(function () {
    if (window.__BOXLINDER_READY) return;
    showErr(
      'Нет box-maker.js на Cargo. Files → Upload → cargo/box-maker.js (~1 MB). Не boxlinder.js 61 KB. Потом ?v=2 в embed.'
    );
  }, 10000);
  window.addEventListener('boxlinder-ready', function () {
    var err = document.getElementById('boxlinder-err');
    if (err) err.remove();
  });
})();
</description>
		
	</item>
		
		
	<item>
		<title>AAAAA</title>
				
		<link>https://nikitavasilevskiy.com/AAAAA</link>

		<pubDate>Mon, 16 Mar 2026 14:56:48 +0000</pubDate>

		<dc:creator>Nikita Vasilevskiy</dc:creator>

		<guid isPermaLink="true">https://nikitavasilevskiy.com/AAAAA</guid>

		<description>
.pinned.pinned_bottom .page_container.overlay{display:none;}
.site-avatar{display:none!important;}

html, body{
  margin:0;
  padding:0;
  background:#8d8d8d!important;
  letter-spacing:0!important;
}

/* нижняя плашка */
#poster-usdz-ar-bar{
  position:fixed;
  left:0;
  right:0;
  bottom:0;
  z-index:10;
  background:#fff;
  padding:12px 0;
  padding-bottom:calc(12px + env(safe-area-inset-bottom, 0px));
  text-align:center;
}

/* сам заголовок */
#poster-usdz-ar-btn{
  margin:0;
  cursor:pointer;
  user-select:none;
}

/* состояние до загрузки */
#poster-usdz-ar-btn.is-disabled{
  opacity:.5;
  cursor:default;
  pointer-events:none;
}



Upload your design in a standard format and place it&#38;nbsp;on&#38;nbsp;your wall using AR. Instantly see how it&#38;nbsp;looks at&#38;nbsp;true size in&#38;nbsp;your space.






  




(function(){
  function fallbackTrigger(){
    try {
      if(navigator.vibrate){ navigator.vibrate(15); return; }
    }catch(e){}
    var toClick=document.getElementById('_hl');
    if(!toClick){
      var cb=document.createElement('input');
      cb.type='checkbox'; cb.id='_h'; cb.setAttribute('aria-hidden','true'); cb.setAttribute('role','switch');
      cb.style.cssText='position:fixed;opacity:0;pointer-events:none;left:-99px;top:0;';
      var lb=document.createElement('label');
      lb.id='_hl'; lb.htmlFor='_h'; lb.setAttribute('aria-hidden','true');
      lb.style.cssText='position:fixed;opacity:0;pointer-events:none;left:-99px;top:0;width:1px;height:1px;';
      document.body.appendChild(cb); document.body.appendChild(lb);
      toClick=lb;
    }
    try{ toClick.click(); }catch(e){}
  }
  window.trigger=function(p,o){ fallbackTrigger(); };
})();


(function(){
  var urls=[
    'https://esm.sh/web-haptics@0.0.6',
    'https://cdn.jsdelivr.net/npm/web-haptics@0.0.6/dist/index.mjs'
  ];
  async function load(){
    for(var i=0;i</description>
		
	</item>
		
		
	<item>
		<title>Stamp Brush</title>
				
		<link>https://nikitavasilevskiy.com/Stamp-Brush</link>

		<pubDate>Fri, 13 Mar 2026 10:52:49 +0000</pubDate>

		<dc:creator>Nikita Vasilevskiy</dc:creator>

		<guid isPermaLink="true">https://nikitavasilevskiy.com/Stamp-Brush</guid>

		<description>

  
    
      Load Brush
    
    Save
    Clear
  

  

  
  



.pinned.pinned_bottom .page_container.overlay{display:none;}
.site-avatar{display:none!important;}

html, body {
  margin: 0;
  padding: 0;
  background: #fff !important;
  letter-spacing: 0rem !important;
}

#image-brush-app{
  position: fixed;
  inset: 0;
  z-index: 9999;
}

#brush-canvas{
  width: 100vw;
  height: 100vh;
  display: block;
  background: transparent;
  touch-action: none;
  cursor: default;
}

html.brush-ready #brush-canvas{
  cursor: crosshair;
}

#brush-upload{
  display: none;
}

#brush-controls{
  position: fixed;
  left: 50%;
  bottom: 3rem;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 1.5rem;
  z-index: 10002;
  user-select: none;
  -webkit-user-select: none;
}

#brush-controls small{
  display: inline-block;
  cursor: pointer;
}

#brush-controls small.is-idle{
  color: rgba(0,0,0,0.28);
}

#brush-upload-label{
  cursor: pointer;
}

#brush-preview{
  position: fixed;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 10001;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  display: none;
}

@media (hover: none), (pointer: coarse) {
  #brush-preview{
    display: none !important;
  }

  /* На тач-устройствах оставляем системный курсор (обычно его нет) */
}



(() =&#62; {
  const canvas = document.getElementById("brush-canvas");
  const ctx = canvas.getContext("2d", { alpha: true });
  const input = document.getElementById("brush-upload");
  const preview = document.getElementById("brush-preview");
  const clearBtn = document.getElementById("clear-canvas");
  const saveBtn = document.getElementById("save-canvas");

  let cw = 0;
  let ch = 0;
  let dpr = 1;

  let brushImg = null;
  let brushReady = false;

  let brushWidth = 160;
  let brushHeight = 160;

  let isDrawing = false;
  let activePointerId = null;
  let lastX = 0;
  let lastY = 0;

  let pointerX = window.innerWidth * 0.5;
  let pointerY = window.innerHeight * 0.5;

  let hasArtwork = false;

  const MIN_SIZE = 16;
  const MAX_SIZE = 1200;
  const SIZE_STEP = 12;
  const SPACING_FACTOR = 0.16;

  const DESKTOP_BASE_SIZE = 160;
  const MOBILE_BASE_SIZE = 80;

  const UNDO_LIMIT = 42;
  const undoStack = [];
  const DEFAULT_BRUSH_URL = "https://freight.cargo.site/t/original/i/9d9579794701d677fb333540065ce79f4741298e92fa1d899ce070410b1777cb/grass.png";

  function setBrushReady(next) {
    brushReady = !!next;
    document.documentElement.classList.toggle("brush-ready", brushReady);
    updatePreview();
  }

  function isCoarsePointer() {
    return window.matchMedia("(hover: none), (pointer: coarse)").matches;
  }

  function updateActionState() {
    clearBtn.classList.toggle("is-idle", !hasArtwork);
    saveBtn.classList.toggle("is-idle", !hasArtwork);
  }

  function markArtworkPresent() {
    if (!hasArtwork) {
      hasArtwork = true;
      updateActionState();
    }
  }

  function resizeCanvas() {
    dpr = Math.max(1, window.devicePixelRatio &#124;&#124; 1);

    const old = document.createElement("canvas");
    old.width = canvas.width;
    old.height = canvas.height;

    if (canvas.width &#38;&#38; canvas.height) {
      old.getContext("2d").drawImage(canvas, 0, 0);
    }

    cw = window.innerWidth;
    ch = window.innerHeight;

    canvas.width = Math.round(cw * dpr);
    canvas.height = Math.round(ch * dpr);

    canvas.style.width = cw + "px";
    canvas.style.height = ch + "px";

    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);

    if (old.width &#38;&#38; old.height) {
      ctx.drawImage(
        old,
        0, 0, old.width, old.height,
        0, 0, cw, ch
      );
    }

    updatePreview();
  }

  function snapshot() {
    if (!canvas.width &#124;&#124; !canvas.height) return;

    const snap = document.createElement("canvas");
    snap.width = canvas.width;
    snap.height = canvas.height;
    snap.getContext("2d").drawImage(canvas, 0, 0);

    undoStack.push(snap);

    if (undoStack.length &#62; UNDO_LIMIT) {
      undoStack.shift();
    }
  }

  function stopDrawing() {
    isDrawing = false;
    activePointerId = null;
  }

  function canvasHasVisiblePixels() {
    if (!canvas.width &#124;&#124; !canvas.height) return false;

    const sample = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
    for (let i = 3; i &#60; sample.length; i += 4) {
      if (sample[i] !== 0) return true;
    }

    return false;
  }

  function syncArtworkStateFromCanvas() {
    hasArtwork = canvasHasVisiblePixels();
    updateActionState();
  }

  function undo() {
    if (!undoStack.length) return;

    const prev = undoStack.pop();

    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(prev, 0, 0);
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);

    stopDrawing();
    syncArtworkStateFromCanvas();
  }

  function clearCanvas() {
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);

    undoStack.length = 0;
    stopDrawing();
    hasArtwork = false;
    updateActionState();
  }

  function saveCanvas() {
    const link = document.createElement("a");
    link.download = "brush-drawing.png";
    link.href = canvas.toDataURL("image/png");
    link.click();
  }

  function getPoint(e) {
    const rect = canvas.getBoundingClientRect();
    return {
      x: e.clientX - rect.left,
      y: e.clientY - rect.top
    };
  }

  function updatePreview() {
    if (!brushReady &#124;&#124; isCoarsePointer()) {
      preview.style.display = "none";
      return;
    }

    preview.style.display = "block";
    preview.style.width = brushWidth + "px";
    preview.style.height = brushHeight + "px";
    preview.style.left = pointerX + "px";
    preview.style.top = pointerY + "px";
  }

  function setBrushSize(size) {
    if (!brushImg) return;

    size = Math.max(MIN_SIZE, Math.min(MAX_SIZE, size));

    const ratio = brushImg.width / brushImg.height;

    if (brushImg.width &#62;= brushImg.height) {
      brushWidth = size;
      brushHeight = size / ratio;
    } else {
      brushHeight = size;
      brushWidth = size * ratio;
    }

    updatePreview();
  }

  function stamp(x, y, angle = 0) {
    if (!brushReady &#124;&#124; !brushImg) return;

    ctx.save();
    ctx.translate(x, y);
    ctx.rotate(angle);
    ctx.drawImage(
      brushImg,
      -brushWidth / 2,
      -brushHeight / 2,
      brushWidth,
      brushHeight
    );
    ctx.restore();
  }

  function drawLine(x1, y1, x2, y2) {
    if (!brushReady &#124;&#124; !brushImg) return;

    const dx = x2 - x1;
    const dy = y2 - y1;
    const dist = Math.hypot(dx, dy);
    const angle = Math.atan2(dy, dx);
    const spacing = Math.max(4, Math.max(brushWidth, brushHeight) * SPACING_FACTOR);

    if (dist === 0) {
      stamp(x1, y1, angle);
      markArtworkPresent();
      return;
    }

    const steps = Math.max(1, Math.floor(dist / spacing));

    for (let i = 0; i  0;
      }
      return (e.buttons &#38; 1) === 1;
    }

    if (e.pointerType === "mouse") {
      return (e.buttons &#38; 1) === 1;
    }

    if (e.pointerType === "touch") {
      return true;
    }

    return (e.buttons &#38; 1) === 1;
  }

  function startDraw(e) {
    const p = getPoint(e);
    pointerX = p.x;
    pointerY = p.y;
    updatePreview();

    if (!brushReady) return;
    if (!isPointerActuallyDrawing(e)) return;

    e.preventDefault();

    snapshot();

    isDrawing = true;
    activePointerId = e.pointerId;
    lastX = p.x;
    lastY = p.y;

    try {
      canvas.setPointerCapture(e.pointerId);
    } catch (_) {}

    stamp(lastX, lastY, 0);
    markArtworkPresent();
  }

  function moveDraw(e) {
    const p = getPoint(e);
    pointerX = p.x;
    pointerY = p.y;
    updatePreview();

    if (!brushReady) return;
    if (!isDrawing) return;
    if (activePointerId !== null &#38;&#38; e.pointerId !== activePointerId) return;

    if (!isPointerActuallyDrawing(e)) {
      stopDrawing();
      return;
    }

    e.preventDefault();

    drawLine(lastX, lastY, p.x, p.y);
    lastX = p.x;
    lastY = p.y;
  }

  function endDraw(e) {
    if (activePointerId !== null &#38;&#38; e.pointerId !== activePointerId) return;

    try {
      canvas.releasePointerCapture(e.pointerId);
    } catch (_) {}

    stopDrawing();
  }

  function loadBrush(src) {
    const img = new Image();
    img.crossOrigin = "anonymous";

    img.onload = () =&#62; {
      brushImg = img;
      preview.style.backgroundImage = `url("${src}")`;

      const baseSize = isCoarsePointer() ? MOBILE_BASE_SIZE : DESKTOP_BASE_SIZE;
      setBrushSize(baseSize);

      setBrushReady(true);
    };

    img.src = src;
  }

  input.addEventListener("change", (e) =&#62; {
    const file = e.target.files &#38;&#38; e.target.files[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = (ev) =&#62; {
      loadBrush(ev.target.result);
    };
    reader.readAsDataURL(file);

    input.value = "";
  });

  clearBtn.addEventListener("click", clearCanvas);
  saveBtn.addEventListener("click", saveCanvas);

  window.addEventListener("keydown", (e) =&#62; {
    const current = Math.max(brushWidth, brushHeight);

    if ((e.ctrlKey &#124;&#124; e.metaKey) &#38;&#38; e.key.toLowerCase() === "z") {
      e.preventDefault();
      undo();
      return;
    }

    if (!brushReady) return;

    if (e.key === "[") {
      e.preventDefault();
      setBrushSize(current - SIZE_STEP);
    }

    if (e.key === "]") {
      e.preventDefault();
      setBrushSize(current + SIZE_STEP);
    }
  });

  canvas.addEventListener("pointerdown", startDraw);
  canvas.addEventListener("pointermove", moveDraw);
  canvas.addEventListener("pointerup", endDraw);
  canvas.addEventListener("pointercancel", endDraw);
  canvas.addEventListener("pointerleave", endDraw);

  window.addEventListener("blur", stopDrawing);
  window.addEventListener("resize", resizeCanvas);

  resizeCanvas();
  loadBrush(DEFAULT_BRUSH_URL);
  updateActionState();
})();
</description>
		
	</item>
		
		
	<item>
		<title>coal</title>
				
		<link>https://nikitavasilevskiy.com/coal</link>

		<pubDate>Tue, 10 Feb 2026 14:12:25 +0000</pubDate>

		<dc:creator>Nikita Vasilevskiy</dc:creator>

		<guid isPermaLink="true">https://nikitavasilevskiy.com/coal</guid>

		<description>
.pinned.pinned_bottom .page_container.overlay{display:none;}
.site-avatar {display:none!important;}

html, body, * {
-webkit-user-select: none !important;
user-select: none !important;
-webkit-touch-callout: none !important;
-webkit-tap-highlight-color: transparent !important;
}

body {
margin: 0 !important;
}

#drawCanvas {
position: fixed;
inset: 0;
width: 100vw;
height: 100vh;
z-index: 999999;
pointer-events: auto;
touch-action: none;
background: transparent;
}




</description>
		
	</item>
		
		
	<item>
		<title>Inflation</title>
				
		<link>https://nikitavasilevskiy.com/Inflation</link>

		<pubDate>Sat, 07 Mar 2026 19:34:07 +0000</pubDate>

		<dc:creator>Nikita Vasilevskiy</dc:creator>

		<guid isPermaLink="true">https://nikitavasilevskiy.com/Inflation</guid>

		<description>
.pinned.pinned_bottom .page_container.overlay{display:none;}
.site-avatar{display:none!important;}

* { box-sizing: border-box; margin: 0; padding: 0; letter-spacing: 0rem!important; }

/* Единые отступы нижней/верхней зоны и межэлементные промежутки */
:root {
  --bottom-zone: 5rem;   /* отступ снизу: draw-hint, status, bottom-bar */
  --top-zone: 2rem;      /* отступ сверху: top-bar */
  --ui-gap: 1.5rem;      /* gap: bottom-bar, top-bar, top-bar-inner */
}

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: fixed;
  background: #000;
  font-family: Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  letter-spacing: 0rem!important;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

#app {
  width: 100%;
  height: 100%;
  position: relative;
  letter-spacing: 0rem!important;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Tab: полный screen-space интерфейс скрыт, canvas (#workspace) остаётся */
#top-bar,
#mirror-line,
#draw-hint,
#bottom-bar,
#status,
#app-version,
#normal-audit,
.debug-panel {
  transition: opacity 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              filter 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              transform 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              visibility 0s linear 0s;
}

#app.ui-chrome-hidden #top-bar,
#app.ui-chrome-hidden #mirror-line,
#app.ui-chrome-hidden #draw-hint,
#app.ui-chrome-hidden #bottom-bar,
#app.ui-chrome-hidden #status,
#app.ui-chrome-hidden #app-version,
#app.ui-chrome-hidden #normal-audit,
#app.ui-chrome-hidden .debug-panel {
  opacity: 0 !important;
  filter: blur(6px) !important;
  visibility: hidden !important;
  pointer-events: none !important;
  transition: opacity 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              filter 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              transform 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              visibility 0s linear 0.45s !important;
}

/* ---- Main viewport (Three.js canvas) ---- */
#workspace {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: #000;
  touch-action: none;
}

#workspace canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
  touch-action: none;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

/* ---- Overlay labels: fade + blur with easing ---- */
.ui-hint {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  pointer-events: none;
  transition: opacity 0.5s cubic-bezier(0.25, 0.1, 0.25, 1),
              filter 0.5s cubic-bezier(0.25, 0.1, 0.25, 1);
}
.ui-hint.hidden {
  opacity: 0;
  filter: blur(8px);
  pointer-events: none;
  visibility: hidden;
  transition: opacity 0.4s cubic-bezier(0.4, 0, 1, 1),
              filter 0.4s cubic-bezier(0.4, 0, 1, 1),
              visibility 0s linear 0.4s;
}

#draw-hint {
  bottom: var(--bottom-zone);
  color: var(--ui-fg-soft);
  font-size: 2rem;
  white-space: nowrap;
  text-align: center;
}

/* ---- Bottom bar: visible after inflate, same fade/blur ---- */
#bottom-bar {
  bottom: var(--bottom-zone);
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: center;
  gap: 1.25rem;
  align-items: center;
  user-select: none;
  opacity: 0;
  filter: blur(6px);
  visibility: hidden;
  pointer-events: none;
  left: 50%;
  max-width: 96vw;
  transform: translateX(-50%) translateY(10px);
  transition: opacity 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              filter 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              transform 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              visibility 0s linear 0.45s;
  will-change: opacity, filter, transform;
}
#bottom-bar.visible {
  opacity: 1;
  filter: blur(0);
  visibility: visible;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
  transition: opacity 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              filter 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              transform 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              visibility 0s linear 0s;
}
#bottom-bar.visible .tap-label {
  pointer-events: auto;
  flex-shrink: 0;
}

.top-controls,
#top-bar {
  position: fixed;
  top: var(--top-zone);
  left: 2rem;
  z-index: 11;
  display: flex;
  align-items: center;
  gap: var(--ui-gap);
  user-select: none;
  padding-top: 0.2em;
  padding-bottom: 0.2em;
  box-sizing: border-box;
}

.top-bar-inner {
  display: flex;
  align-items: center;
  gap: var(--ui-gap);
}

/* На мобильных: панель от края до края, контент с отступами — обрезка не по буквам */
@media (max-width: 768px), (hover: none) {
  :root {
    --bottom-zone: 4.5rem;
    --top-zone: 1rem;
  }
  #top-bar {
    left: 0;
    right: 0;
    max-width: 100%;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scroll-behavior: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  #top-bar::-webkit-scrollbar {
    display: none;
  }
  .top-bar-inner {
    padding-left: 1rem;
    padding-right: 1rem;
    flex-shrink: 0;
    flex-wrap: nowrap;
  }
  #top-bar .tap-label {
    flex-shrink: 0;
    touch-action: manipulation;
  }
  #bottom-bar {
    left: 0;
    right: 0;
    max-width: 100%;
    padding-left: 0.75rem;
    padding-right: 0.75rem;
    gap: 0.85rem;
    transform: translateY(10px);
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    justify-content: center;
  }
  #bottom-bar::-webkit-scrollbar {
    display: none;
  }
  #bottom-bar.visible {
    transform: translateY(0);
  }
}

label.tap-label {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.tap-label {
  color: var(--ui-fg-muted);
  font-size: 2rem;
  cursor: pointer;
  touch-action: manipulation;
  transition: color 0.2s ease;
  white-space: nowrap;
}

.tap-label.active,
.tap-label[aria-pressed="true"] {
  color: var(--ui-accent);
}

.tap-label:focus,
.tap-label:focus-visible {
  outline: none;
  box-shadow: none;
}

.tap-label-corner {
  line-height: 1;
  user-select: none;
}

@media (hover: hover) {
  .tap-label:hover {
    color: var(--ui-accent);
  }
  .tap-label[aria-disabled="true"]:hover {
    color: var(--ui-fg-muted);
  }
}
.tap-label[aria-disabled="true"] {
  opacity: 0.35;
  cursor: default;
}

#status {
  position: fixed;
  bottom: var(--bottom-zone);
  left: 50%;
  transform: translateX(-50%) translateY(10px);
  font-size: 2rem;
  line-height: 1.1;
  color: var(--ui-fg-muted);
  z-index: 10;
  pointer-events: none;
  text-align: center;
  white-space: nowrap;
  opacity: 0;
  filter: blur(6px);
  visibility: hidden;
  transition: opacity 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              filter 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              transform 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              visibility 0s linear 0.45s,
              color 0.25s ease;
  will-change: opacity, filter, transform;
}
#status.status-error {
  color: #e85c5c;
}
#status.visible {
  opacity: 1;
  filter: blur(0);
  visibility: visible;
  transform: translateX(-50%) translateY(0);
  transition: opacity 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              filter 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              transform 0.45s cubic-bezier(0.25, 0.1, 0.25, 1),
              visibility 0s linear 0s;
}
#status.status-immediate,
#status.status-immediate.visible {
  filter: blur(0);
  transition: opacity 0.12s ease,
              filter 0s linear,
              transform 0.12s ease,
              visibility 0s linear 0s;
}

#app-version {
  position: fixed;
  bottom: 1rem;
  left: 1rem;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--ui-fg-soft);
  z-index: 5;
  pointer-events: none;
  transition: color 0.25s ease;
}
#app-version a {
  color: inherit;
  text-decoration: none;
  pointer-events: auto;
  cursor: pointer;
}
#app-version a:hover {
  color: var(--ui-fg-muted);
}

#mirror-line {
  position: fixed;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 1px;
  transform: translateX(-50%);
  background: var(--ui-line);
  pointer-events: none;
  z-index: 5;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, visibility 0s linear 0.2s;
}
#mirror-line.visible {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.2s ease;
}

#normal-audit.footer-link {
  position: fixed;
  bottom: 1rem;
  right: 1rem;
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--ui-fg-soft);
  z-index: 5;
  cursor: pointer;
  pointer-events: auto;
  transition: color 0.2s ease;
}

#normal-audit.footer-link:hover {
  color: var(--ui-fg-muted);
}

#normal-audit.footer-link:focus,
#normal-audit.footer-link:focus-visible {
  outline: none;
}

body.gp-recording::after {
  content: "";
  position: fixed;
  right: 24px;
  top: 24px;
  z-index: 2147483647;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  background: #ff1d1d;
  pointer-events: none;
  animation: gp-rec-pulse 1.1s ease-in-out infinite;
}

@keyframes gp-rec-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

#inflation-bg-color-input {
  position: fixed !important;
  left: 50% !important;
  top: 50% !important;
  transform: translate(-50%, -50%) !important;
  z-index: 2147483647 !important;
  width: 56px !important;
  height: 56px !important;
  margin: 0 !important;
  padding: 0 !important;
  border: none !important;
  cursor: pointer;
  opacity: 0.001;
  pointer-events: none;
}

label#btn-background {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* ---- Side panel: material and light (right) ---- */
.debug-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 420px;
  max-width: 92vw;
  z-index: 20;
  background: rgba(0, 0, 0, 0.2);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  color: var(--ui-panel-fg);
  font-family: Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 1.15rem;
  letter-spacing: normal !important;
  overflow-y: auto;
  padding: 1.25rem 1rem 1.25rem 1rem;
  transition: transform 0.25s ease;
}
.debug-panel.debug-panel-hidden {
  transform: translateX(100%);
  pointer-events: none;
}
.debug-panel h3 {
  font-family: inherit;
  font-size: 1.15rem;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal !important;
  color: var(--ui-panel-fg);
  margin: 0.9rem 0 0.3rem;
  padding: 0;
}
.debug-panel h3:first-child { margin-top: 0; }
.debug-panel .row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.28rem 0;
  padding: 0;
}
.debug-panel label {
  flex: 0 0 95px;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: inherit;
  font-size: inherit;
  letter-spacing: normal !important;
  color: var(--ui-panel-fg);
}
.debug-panel input[type="range"] {
  flex: 1;
  min-width: 0;
  accent-color: var(--ui-accent-soft);
  outline: none;
  border: 0;
}
.debug-panel input[type="range"]:focus,
.debug-panel input[type="range"]:focus-visible {
  outline: none;
  box-shadow: none;
}
.debug-panel .num {
  flex: 0 0 52px;
  min-width: 0;
  font-family: inherit;
  font-size: inherit;
  font-variant-numeric: tabular-nums;
  letter-spacing: normal !important;
  text-align: right;
  color: var(--ui-accent);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--ui-border);
  padding: 0.1rem 0 1px 0;
  outline: none;
}
.debug-panel .num::-webkit-outer-spin-button,
.debug-panel .num::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.debug-panel .num[type="number"] {
  -moz-appearance: textfield;
}

@media (max-width: 768px) {
  .tap-label,
  #draw-hint,
  #status {
    font-size: 1.5rem;
  }
  #bottom-bar .tap-label {
    font-size: 1.35rem;
  }
}


Inflation turns a 2D drawing into a 3D shape: you draw a closed contour on the canvas, and the app builds a smooth 3D mesh from it. You can rotate the result, switch reflection environments with number keys, and export the model as USDZ for AR Quick Look on iOS.

      
        
      
      
        
          Load Texture
          Load Shape
          Mirror Drawing
          Background
        
      
      
      
      
      
      Draw a shape
      
        Clear
        PNG
        Video
        USDZ
      
      
      
      Download Report Log
  
</description>
		
	</item>
		
		
	<item>
		<title>gravity-drawing</title>
				
		<link>https://nikitavasilevskiy.com/gravity-drawing</link>

		<pubDate>Thu, 30 Apr 2026 11:56:15 +0000</pubDate>

		<dc:creator>Nikita Vasilevskiy</dc:creator>

		<guid isPermaLink="true">https://nikitavasilevskiy.com/gravity-drawing</guid>

		<description>

  



  .pinned.pinned_bottom .page_container.overlay {
    display: none;
  }

  .site-avatar {
    display: none !important;
  }

  html, body, * {
    -webkit-user-select: none !important;
    user-select: none !important;
    -webkit-touch-callout: none !important;
    -webkit-tap-highlight-color: transparent !important;
    letter-spacing: 0 !important;
  }

  body {
    margin: 0 !important;
  }

  #gravity-draw-root {
    width: 100%;
    height: min(100vh, 100svh);
    position: relative;
    background: transparent;
    overflow: hidden;
  }

  #gravity-draw-root #app-canvas {
    width: 100%;
    height: 100%;
    display: block;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
    -webkit-tap-highlight-color: transparent;
  }

  #version-badge {
    position: fixed;
    left: 8px;
    bottom: 8px;
    font-size: 10px;
    line-height: 100%;
    color: rgba(35, 35, 35, 0.8);
    pointer-events: none;
    z-index: 10;
  }




</description>
		
	</item>
		
		
	<item>
		<title>raycast playground</title>
				
		<link>https://nikitavasilevskiy.com/raycast-playground</link>

		<pubDate>Tue, 24 Feb 2026 18:20:05 +0000</pubDate>

		<dc:creator>Nikita Vasilevskiy</dc:creator>

		<guid isPermaLink="true">https://nikitavasilevskiy.com/raycast-playground</guid>

		<description>
  // Ensure mobile viewport is set (in case Cargo theme doesn't include it)
  if (!document.querySelector('meta[name="viewport"]')) {
    const m = document.createElement('meta');
    m.name = 'viewport';
    m.content = 'width=device-width, initial-scale=1.0';
    document.head.appendChild(m);
  }


    .pinned.pinned_bottom .page_container.overlay{display:none;}
    .site-avatar{display:none!important;}
    .content_padding { padding: 0 !important; }
    .page_content { padding: 0 !important; margin: 0 !important; }
    * { box-sizing: border-box; }
    .gallery-cargo button:focus,
    .gallery-cargo input:focus,
    .gallery-cargo input[type="range"]:focus { outline: none; }
    .gallery-cargo {
      margin: 0;
      padding: 0;
      height: 100vh;
      overflow: hidden; background: #1a1a1a;
      color: #e0e0e0;
    }
    .gallery-cargo .layout {
      position: relative;
      width: 100%;
      height: 100%;
    }
    .gallery-cargo .preview-pane {
      position: absolute;
      inset: 0;
      width: 100%;
      background: #0a0a0a;
      display: flex;
      flex-direction: column;
    }
    .gallery-cargo .preview-container {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
    }
    .gallery-cargo #game {
      max-width: 100%;
      max-height: 100%;
      display: block;
      touch-action: none;
    }
    .gallery-cargo .editor-pane {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      width: 25%;
      min-width: 220px;
      padding: 0;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      gap: 0;
      background: var(--floor-fg, #000);
      border: 1px solid var(--floor-fg, #000);
      box-sizing: border-box;
      color: var(--floor-fg-inv, #fff);
      font: 400 2rem/1 "Inter", sans-serif;
      --floor-color: #41B649;
      --floor-fg: #000;
      container-type: inline-size;
      --cell-size: calc(100cqw / 16);
      z-index: 10;
    }
    .editor-pane h1 { display: none; }
    .gallery-cargo .color-settings {
      display: flex;
      flex-direction: column;
      gap: 0;
    }
    .gallery-cargo .color-btn {
      padding: 0 0 0 0.2em;
      border: none;
      border-radius: 0;
      cursor: pointer;
      font: 400 2rem/1 "Inter", sans-serif;
      color: #fff;
      position: relative;
      height: calc(var(--cell-size) * 2);
      min-height: calc(var(--cell-size) * 2);
      display: flex;
      align-items: center;
      justify-content: flex-start;
      box-shadow: inset 0 0 0 1px var(--floor-fg, #000);
    }
    .color-btn span,
    .color-btn-wrap span {
      font: 400 2rem/1 "Inter", sans-serif;
      text-align: left;
    }
    button.color-btn {
      font: 400 2rem/1 "Inter", sans-serif;
    }
    .color-btn input[type="color"] {
      position: absolute;
      opacity: 0;
      inset: 0;
      cursor: pointer;
      width: 100%;
      height: 100%;
      z-index: 1;
    }
    .gallery-cargo .color-btn-wrap {
      display: flex;
      align-items: center;
      justify-content: flex-start;
      gap: 0;
      width: 100%;
      height: 100%;
      padding: 0;
      font: 400 2rem/1 "Inter", sans-serif;
    }
    .gallery-cargo .color-btn .btn-tex {
      box-shadow: inset 0 0 0 1px var(--floor-fg, #000);
    }
    .color-btn-wrap .toggle {
      width: calc(var(--cell-size) * 2);
      height: calc(var(--cell-size) * 2);
      min-width: calc(var(--cell-size) * 2);
      border: 2px solid var(--toggle-fg, #fff);
      border-radius: 50%;
      background: transparent;
      box-shadow: inset 0 0 0 1px var(--floor-fg, #000);
      cursor: pointer;
      flex-shrink: 0;
      position: relative;
      z-index: 2;
      margin: 0;
      padding: 0;
    }
    .color-btn-wrap .toggle.on {
      background: var(--toggle-fg, #fff);
    }
    .gallery-cargo .shadow-slider {
      -webkit-appearance: none;
      appearance: none;
      width: calc(var(--cell-size) * 8);
      min-width: calc(var(--cell-size) * 8);
      height: calc(var(--cell-size) * 2);
      background: transparent;
      cursor: pointer;
      margin-left: auto;
      flex-shrink: 0;
      position: relative;
      z-index: 2;
      padding: 0;
      border: none;
      outline: none;
    }
    .gallery-cargo .shadow-slider::-webkit-slider-runnable-track {
      height: 1px;
      background: var(--toggle-fg, #fff);
    }
    .gallery-cargo .shadow-slider::-webkit-slider-thumb {
      -webkit-appearance: none;
      width: calc(var(--cell-size) * 2);
      height: calc(var(--cell-size) * 2);
      border-radius: 50%;
      background: var(--toggle-fg, #fff);
      margin-top: calc(var(--cell-size) * -1);
      cursor: pointer;
    }
    .gallery-cargo .shadow-slider::-moz-range-track {
      height: 1px;
      background: var(--toggle-fg, #fff);
      border: none;
    }
    .gallery-cargo .shadow-slider::-moz-range-thumb {
      width: calc(var(--cell-size) * 2);
      height: calc(var(--cell-size) * 2);
      border-radius: 50%;
      background: var(--toggle-fg, #fff);
      border: none;
      cursor: pointer;
    }
    .gallery-cargo .btn-tex {
      width: calc(var(--cell-size) * 2);
      height: calc(var(--cell-size) * 2);
      min-width: calc(var(--cell-size) * 2);
      flex-shrink: 0;
      position: relative;
      z-index: 2;
      padding: 0;
      border: none;
      border-radius: 0;
      cursor: pointer;
    }
    .gallery-cargo .color-btn.has-tex input[type="color"] {
      pointer-events: none;
    }
    .gallery-cargo .toolbar { display: none; }
    .gallery-cargo .toolbar-fixed {
      position: fixed;
      right: calc(25vw / 16 * 2);
      bottom: 0;
      width: calc(25% - 25vw / 16 * 2);
      min-width: 0;
      display: flex;
      align-items: stretch;
      gap: 0;
      z-index: 100;
      --tb-cell: calc(25vw / 16);
    }
    .gallery-cargo .toolbar-toggle-only {
      position: fixed;
      right: 0;
      bottom: 0;
      z-index: 101;
      --tb-cell: calc(25vw / 16);
      display: flex;
      align-items: stretch;
      height: calc(var(--tb-cell) * 2);
    }
    .gallery-cargo .btn-info {
      width: calc(var(--tb-cell) * 2);
      height: calc(var(--tb-cell) * 2);
      flex-shrink: 0;
      border: none;
      border-radius: 50%;
      background: var(--floor-color, #41B649);
      box-shadow: inset 0 0 0 1px var(--floor-fg, #000);
      color: var(--floor-fg, #000);
      font-size: 1.6rem;
      font-weight: 600;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .btn-info:hover { background: #CCFF00; color: #000; }
    .btn-info.active {
      background: #CCFF00;
      color: #000;
    }
    .gallery-cargo .btn-toggle-panel {
      width: calc(var(--tb-cell) * 2);
      height: calc(var(--tb-cell) * 2);
      min-height: 0;
      flex-shrink: 0;
      border: none;
      border-radius: 50%;
      margin: 0;
      padding: 0;
      background: #CCFF00;
      cursor: pointer;
      box-shadow: inset 0 0 0 1px var(--floor-fg, #000);
    }
    .btn-toggle-panel:hover,
    .btn-toggle-panel.hidden { background: #CCFF00; }
    .editor-pane.collapsed {
      width: 0;
      min-width: 0;
      overflow: hidden;
      border: none;
    }
    .gallery-cargo .description-panel {
      display: none;
      flex: 1 1 0;
      min-height: 0;
      overflow-y: auto;
      padding: 0;
      background: var(--floor-fg, #000);
    }
    .editor-pane.mode-description .color-settings,
    .editor-pane.mode-description .grid-container,
    .editor-pane.mode-description .palette-scroll {
      display: none;
    }
    .editor-pane.mode-description .description-panel {
      display: block;
    }
    .gallery-cargo .description-content {
      font-size: 2rem;
      font-weight: 400;
      color: var(--floor-fg-inv, #fff);
    }
    .description-content p { margin: 0; padding: 0; line-height: 1; }
    .editor-pane.collapsed .toolbar-fixed {
      display: none;
    }
    .gallery-cargo .asset-section {
      margin: 0;
      flex-shrink: 0;
      background: var(--floor-fg, #000);
      border-radius: 0;
      padding: 0;
    }
    .asset-section + .asset-section { margin-top: 0; }
    .gallery-cargo .palette-scroll {
      flex: 1 1 0;
      min-height: 0;
      overflow-y: auto;
      background: var(--floor-fg, #000);
      padding: 0;
    }
    .gallery-cargo .asset-section-title {
      display: none;
    }
    .gallery-cargo .asset-row {
      display: block;
    }
    .texture-grid .btn-add, .texture-grid .btn-delete,
    .sprite-grid .btn-add, .sprite-grid .btn-delete {
      flex-shrink: 0;
      width: calc(var(--cell-size) * 2);
      height: calc(var(--cell-size) * 2);
      min-width: 0;
      padding: 0;
      aspect-ratio: unset;
      box-shadow: inset 0 0 0 1px var(--floor-fg, #000);
    }
    .gallery-cargo .btn-add,
    .gallery-cargo .btn-delete {
      border: none;
      border-radius: 0;
      padding: 0;
      cursor: pointer;
      flex-shrink: 0;
      font: 400 2rem/1 sans-serif;
      color: transparent;
      aspect-ratio: 1;
    }
    .gallery-cargo .btn-add {
      background: 0 0 / 100% 100% no-repeat var(--floor-color, #41B649);
      min-width: 0;
      min-height: 0;
    }
    .btn-add:hover { background-color: #CCFF00 !important; }
    .btn-static:hover { background-color: #CCFF00 !important; background-image: linear-gradient(var(--toggle-fg, #000) 50%, transparent 50%) !important; }
    .gallery-cargo .btn-delete {
      background: linear-gradient(to bottom right, var(--floor-color, #41B649) 50%, var(--floor-fg, #000) 50%);
    }
    .btn-delete:hover, .btn-delete.active { background-image: linear-gradient(to bottom right, #CCFF00 50%, var(--floor-fg, #000) 50%) !important; }
    .btn-delete.active { outline: 2px solid #000; outline-offset: 2px; }
    .gallery-cargo .texture-grid,
    .gallery-cargo .sprite-grid {
      display: flex;
      flex-direction: row;
      flex-wrap: nowrap;
      overflow-x: auto;
      overflow-y: hidden;
      -webkit-overflow-scrolling: touch;
      scrollbar-width: thin;
      scrollbar-color: var(--floor-color, #41B649) transparent;
      gap: 0;
      padding-bottom: 0;
    }
    .gallery-cargo .texture-grid::-webkit-scrollbar,
    .gallery-cargo .sprite-grid::-webkit-scrollbar { height: 3px; }
    .gallery-cargo .texture-grid::-webkit-scrollbar-track,
    .gallery-cargo .sprite-grid::-webkit-scrollbar-track { background: transparent; }
    .gallery-cargo .texture-grid::-webkit-scrollbar-thumb,
    .gallery-cargo .sprite-grid::-webkit-scrollbar-thumb { background: var(--floor-color, #41B649); }
    .gallery-cargo .texture-thumb, .gallery-cargo .sprite-thumb {
      flex-shrink: 0;
      width: calc(var(--cell-size) * 2);
      height: calc(var(--cell-size) * 2);
      aspect-ratio: unset;
      object-fit: cover;
      border: none;
      border-radius: 0;
      cursor: pointer;
      background: transparent;
      display: block;
      outline: 1px solid var(--floor-fg, #000);
      outline-offset: -1px;
    }
    .gallery-cargo .sprite-thumb { object-fit: contain; }
    .texture-thumb:hover, .sprite-thumb:hover { outline: 2px solid #CCFF00; outline-offset: -2px; }
    .texture-thumb.selected, .sprite-thumb.selected { outline: 3px solid #CCFF00; outline-offset: -3px; background-color: #CCFF00; }
    .gallery-cargo .grid-container {
      position: relative;
      flex: 0 0 auto;
      overflow: hidden;
      padding: 0;
      width: 100%;
    }
    .grid-container label {
      display: none;
    }
    .gallery-cargo #editor-grid {
      display: grid;
      grid-template-columns: repeat(16, 1fr);
      grid-template-rows: repeat(16, 1fr);
      touch-action: none;
      gap: 0;
      aspect-ratio: 1;
      width: 100%;
      max-width: 100%;
      padding: 0;
    }
    .gallery-cargo .cell {
      position: relative;
      min-width: 0;
      min-height: 0;
      background: var(--floor-color);
      background-size: cover;
      background-position: center;
      cursor: pointer;
      box-shadow: inset 0 0 0 1px var(--floor-fg, #000);
    }
    .cell:hover { outline: none; }
    .cell.sprite { background-size: contain; }
    .gallery-cargo .cell-preview {
      display: none;
      position: absolute;
      inset: 0;
      border: none;
      outline: none;
      border-radius: 0;
      pointer-events: none;
      align-items: center;
      justify-content: center;
      box-shadow: inset 0 0 0 1px var(--floor-fg, #000);
    }
    .gallery-cargo .player-pov {
      position: absolute;
      width: var(--cell-size);
      height: var(--cell-size);
      pointer-events: none;
      border: none;
      outline: none;
    }
    .gallery-cargo .player-pov-circle {
      position: absolute;
      inset: 0;
      border-radius: 50%;
      background: var(--floor-fg, #000);
      border: none;
      outline: none;
      z-index: 0;
    }
    .gallery-cargo .player-pov-stick {
      position: absolute;
      left: 50%;
      top: 0;
      width: 2px;
      height: calc(var(--cell-size) * 0.5);
      margin-left: -1px;
      background: var(--floor-fg-inv, #fff);
      transform-origin: 50% 100%;
      transform: rotate(var(--pov-angle, 0deg));
      z-index: 1;
    }
  
.gallery-cargo { width: 100%; }
@media (max-width: 768px) {
  .gallery-cargo .editor-pane {
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100% !important;
    height: 100% !important;
    min-width: 0;
    --cell-size: calc(100vw / 16);
    transition: transform 0.25s ease;
  }
  .gallery-cargo .editor-pane.collapsed {
    width: 100% !important;
    min-width: 0;
    height: 100% !important;
    transform: translateX(100%);
    border: none;
  }
  .gallery-cargo .toolbar-fixed {
    --tb-cell: calc(100vw / 16);
    right: calc(100vw / 16 * 2);
    width: calc(100% - 100vw / 16 * 2);
  }
  .gallery-cargo .toolbar-toggle-only {
    --tb-cell: calc(100vw / 16);
  }
  .gallery-cargo #btn-shadow { display: none; }
  .gallery-cargo .texture-grid, .gallery-cargo .sprite-grid { scrollbar-width: none; }
  .gallery-cargo .texture-grid::-webkit-scrollbar,
  .gallery-cargo .sprite-grid::-webkit-scrollbar { display: none; }
}
#loading-screen {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
  z-index: 5;
}
@keyframes loading-rainbow {
  0%   { fill: #ff2020; }
  16%  { fill: #ff9900; }
  33%  { fill: #ffee00; }
  50%  { fill: #00dd44; }
  66%  { fill: #0088ff; }
  83%  { fill: #aa00ff; }
  100% { fill: #ff2020; }
}
#loading-screen svg {
  height: 50%;
  width: 37.5%;
  max-width: 37.5%;
  animation: loading-rainbow 1.8s linear infinite;
}
.joystick {
  position: fixed;
  display: none;
  width: 110px;
  height: 110px;
  border-radius: 50%;
  border: 2px solid #fff;
  background: #fff;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 200;
  transform: translate(-50%, -50%);
  box-sizing: border-box;
}
.joystick-thumb {
  position: absolute;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: #000;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}




    
      
        
        
      
    
    
      
        
          
            
            
            
            +
            ×
          
        
        
          
            
            
            +
            ×
          
        
        
          
            
            
            
          
        
      
      
        
        
          
          
        
      
      
        
          WALL
          
            
              +
              ×
            
          
        
        
          SPRITE
          
            
              +
              ×
            
          
        
      
      
        
          
RAYCATS PLAYGROUND™
ADVANCED 16×16 REAL-TIME 3D CONSTRUCTION SYSTEM.

POWERED BY THE KINITOS HYPER-GRID ENGINE™.
BUILD MASSIVE THREE-DIMENSIONAL WORLDS FROM CLASSIC VOXEL CUBES.
IMPORT YOUR OWN TEXTURES. DEPLOY TRANSPARENT SPRITES.
CREATE STRUCTURES NEVER BEFORE POSSIBLE ON A HOME COMPUTER.

FEATURES INCLUDE:

• REAL-TIME 3D MOVEMENT
• WASD STRAFING CONTROL SYSTEM
• PRECISION ARROW-KEY ROTATION
• FULL TOUCH SUPPORT — TAP. DRAG. COMMAND.
• DUAL SKY RENDERING MODES
• PERSPECTIVE-MAPPED GROUND ENGINE
• PNG &#38;amp; GIF TRANSPARENCY PROCESSOR
• DYNAMIC SHADOW INTENSITY SLIDER
• INFINITE CREATIVE CONFIGURATIONS


PAINT THE SKY WITH DIGITAL FIRE.
FLOOD THE GROUND WITH COLOR.
LOAD YOUR OWN IMAGES INTO THE GRID.
WATCH THE WORLD SHIFT AS YOU MOVE.

NO COINS REQUIRED.
NO LOADING TIMES.
JUST PURE PIXEL POWER.

EPILEPSY WARNING: THIS EXPERIENCE MAY CONTAIN FLASHING LIGHTS OR RAPID VISUAL PATTERNS. VIEWER DISCRETION ADVISED.

V.35 © 1987–2026 KINITOS COMPUTER TECHNOLOGIES
FOR HOME COMPUTER SYSTEMS
        
      
      
        i
      
    
    
      
    
  
  
  
  
   
  
  
    
  
  
    
  



    [
      "https://freight.cargo.site/t/original/i/27b63c9a7f5f721d4bde79fb2482823de5c76f53c3b4ab8288a36943ff1ebca7/wall.png",
      "https://freight.cargo.site/t/original/i/3245607061ee5ffb3ae7c4a948d495ed1f947dca5d0e8354e23d778d1acd4211/wall-gold.png",
      "https://freight.cargo.site/t/original/i/6911f5207b1984b11b8969190924efea4c53461ff384084aeaa4fd0791f2af7a/floor.png",
      "https://freight.cargo.site/w/1500/q/75/i/9a245f4380887f29e410583f672827a91cb3c2d7a0b6297d16cdcf16523ece04/Asset-1.png",
      "https://freight.cargo.site/w/1024/q/94/i/8db657ccaf2c6f222749ae141d6ba9f04a76e6416aada0c7faecec7546dca1af/luh-sphere-4.gif",
      "https://freight.cargo.site/w/1000/q/94/i/c07ec70782ecca4f72555d4f9400c5eec792b7373b800d248f224d9bd2f40a24/boss-2.gif",
      "https://freight.cargo.site/w/1080/q/94/i/c3fe95541f36267e1814c9191a1567cc9af6231084871491990fa4c3afefe01e/Ronny-2.jpg",
      "https://freight.cargo.site/w/1000/q/94/i/a0eca9a1dec24ef7caa3a63eaf713b7d1351edadfccac617884aaf22fe45622a/girl.png",
      "https://freight.cargo.site/w/800/q/94/i/8990078a456d583ca7a17a71c2a403c349f4848f4e2ab250e2f3f5ffdde5d62b/gpd.png",
      "https://freight.cargo.site/w/2000/q/94/i/a1ff5bee01d2843c89d80cb3f95b42e924ff8cfdef7beeea680b6bd581e36338/brick-constructor.png",
      "https://freight.cargo.site/w/540/q/94/i/ba0c71d0771d9116ddc15476cb6eee59a7e63d2346f1838e243547b2cb52e125/wave_animation-sf.gif",
      "https://freight.cargo.site/w/600/q/75/i/66ac611e0f0e6a365dac1f805f3b14298282ff606052ee8e86fa0af6f8d51a66/elephant-2.gif",
      "https://freight.cargo.site/w/1500/q/75/i/ea416328f719810a4c356386249b0c2e22d7e1c90804a1a6d167bf68474ead17/luh-25.png",
      "https://freight.cargo.site/w/1200/q/94/i/59a5261157f0d65ba9376a519aa14f8c7bc8bd150628784f6a095282a1c01dcf/inopl.jpg",
      "https://freight.cargo.site/w/1200/q/94/i/a72ab3c80c0e1ce4ff88278fa9d0dd730578c87490ea9642f762c86ad4b0daca/watermelon.png",
      "https://freight.cargo.site/w/960/q/94/i/7fd2e7f374bc59dce9d466c0125e1c6cba506184781878345360706231452ce4/somemart-globe-delivery.gif",
      "https://freight.cargo.site/w/681/q/94/i/91eb0c3610dad6913d1873144943fe83b1828d814f1deaf452d0008002651891/nice-rice-logo-animation.gif",
      "https://freight.cargo.site/w/900/q/75/i/16c30de9049ad7cc2f81b2722ffd406e2c97ebe0a528ec9215a4bad7e0d51c80/cc-a3.gif",
      "https://freight.cargo.site/w/900/q/75/i/bfa74465ca1884b465bdac306240dc323c5766a169b691fe9a35b132c03b50d9/cc-b2.gif",
      "https://freight.cargo.site/w/900/q/75/i/95917e5701b3a228d5fc1a6c0abebdf5fcf43ce09b6563a7afca82c3418c6ec3/BEW-AVA-2.gif",
      "https://freight.cargo.site/w/900/q/75/i/79d4a6c23e78b44b02fdac226d4ee2acc51c09c241fec3230dfc1371d9df80fa/luh.jpg",
      "https://freight.cargo.site/w/1000/q/75/i/99296f405a96c51f9cd614f9d41b55f634a58d6d92c2036d4f15c2cf6a00050b/pil4.gif",
      "https://freight.cargo.site/w/1000/q/75/i/6ef6e92c84519f27c61fd9a4814ae6b790f443324b128c231827448b135c93ba/Asset-1.png",
      "https://freight.cargo.site/t/original/i/2692e90dd31ac4c3dd96b2f12dd54686e07afbce310755b6a4bab59e8941e8ec/Asset-1.png",
      "https://freight.cargo.site/t/original/i/f7a08ee5ecd87ccce84287aa703d3fa3361578841c6914244b78505620461dc6/head-rotation-red.gif"
    ]
  

    [
{"path": "https://freight.cargo.site/t/original/i/3b19b1e7f04b436772d8d242db2dccfdef373b5cc63a30b5106672ba6e3d087e/budtha.png"},
{"path": "https://freight.cargo.site/t/original/i/f8276b6f2d88bbc718983ad0f11989d32ef87957f18e50244991abaca8312b2f/chel-sprite.png"},
{"path": "https://freight.cargo.site/t/original/i/037def2598d47c97347f4aec0340adb83cf0dc3c4cc97f41f88c90dffa303063/tree.png"},
{"path": "https://freight.cargo.site/t/original/i/c675d6788ed7688a642a4ef2e7dafbb02f012718ed801f35b1c407ae87511ff1/rose.png"},
{"path": "https://freight.cargo.site/t/original/i/974d2608408a1be237c77dca12c22cf74a79aa0b7136418bbee741922046821d/source.gif"},
{"path": "https://freight.cargo.site/t/original/i/5d12874bb4f02c311bce41cd547d27c1d6fe4dacc9dd8584c893e3fd39c321e8/raycast-playground.png"},
{"path": "https://freight.cargo.site/t/original/i/543143e320c4b996e76c83c490f5f6d82b4e4c070c6ecb1384df0075596c863a/boy-from-kyoto.png"},
{"path": "https://freight.cargo.site/t/original/i/eda7d03f5a64d37cfca0fe7cbf200536c6b9b3234fef0e4034c6f164d6c0fb50/cat.png"},
{"path": "https://freight.cargo.site/t/original/i/70a47491dfb3171c6d38167423d39029c0f75e4121f2919e8aed7724e4e992ac/flying-chel.png"}
    ]
  





(function(){
  function fallbackTrigger(){
    try { if(navigator.vibrate){ navigator.vibrate(15); return; } }catch(e){}
    var toClick=document.getElementById('_hl');
    if(!toClick){
      var cb=document.createElement('input');
      cb.type='checkbox'; cb.id='_h'; cb.setAttribute('aria-hidden','true'); cb.setAttribute('role','switch');
      cb.style.cssText='position:fixed;opacity:0;pointer-events:none;left:-99px;top:0;';
      var lb=document.createElement('label');
      lb.id='_hl'; lb.htmlFor='_h'; lb.setAttribute('aria-hidden','true');
      lb.style.cssText='position:fixed;opacity:0;pointer-events:none;left:-99px;top:0;width:1px;height:1px;';
      document.body.appendChild(cb); document.body.appendChild(lb);
      toClick=lb;
    }
    try{ toClick.click(); }catch(e){}
  }
  window.trigger=function(p,o){ fallbackTrigger(); };
})();


(function(){
  var urls=[
    'https://esm.sh/web-haptics@0.0.6',
    'https://cdn.jsdelivr.net/npm/web-haptics@0.0.6/dist/index.mjs'
  ];
  async function load(){
    for(var i=0;i</description>
		
	</item>
		
		
	<item>
		<title>PEEL</title>
				
		<link>https://nikitavasilevskiy.com/PEEL</link>

		<pubDate>Sun, 10 May 2026 09:03:36 +0000</pubDate>

		<dc:creator>Nikita Vasilevskiy</dc:creator>

		<guid isPermaLink="true">https://nikitavasilevskiy.com/PEEL</guid>

		<description>

.pinned.pinned_bottom .page_container.overlay {
  display: none;
}

.site-avatar {
  display: none !important;
}

/* Единые отступы нижней/верхней зоны и межэлементные промежутки (как в Photo Nadduv) */
:root {
  --bottom-zone: 5rem;
  --top-zone: 2rem;
  --ui-gap: 1.5rem;
}

@media (max-width: 768px), (hover: none) {
  :root {
    --bottom-zone: 4.5rem;
    --top-zone: 1rem;
  }
}

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: fixed;
  background: #000 !important;
  font-family: Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  letter-spacing: 0rem !important;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

html,
body,
* {
  -webkit-user-select: none !important;
  user-select: none !important;
  -webkit-touch-callout: none !important;
  -webkit-tap-highlight-color: transparent !important;
}

body {
  margin: 0 !important;
}

#peel-app {
  --peel-stage-height: 320px;
  --page-pad: 1rem;
  --text-primary: rgba(211, 194, 186, 0.48);
  --text-strong: #d3c2ba;
  --text-muted: rgba(211, 194, 186, 0.35);
  --ease-standard: cubic-bezier(0.25, 0.1, 0.25, 1);
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);

  isolation: isolate;
  position: relative;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  width: 100%;
  min-height: 100vh;
  min-height: 100dvh;
  height: 100vh;
  height: 100dvh;
  max-height: 100vh;
  max-height: 100dvh;
  overflow: hidden;
  overscroll-behavior: none;
  background: #000;
  color: var(--text-strong);
  font-family: Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  letter-spacing: 0 !important;
  touch-action: none;
}

#peel-app *,
#peel-app *::before,
#peel-app *::after {
  box-sizing: border-box;
  letter-spacing: 0 !important;
}

#peel-app .peel-stage {
  position: relative !important;
  top: auto !important;
  right: auto !important;
  bottom: auto !important;
  left: auto !important;
  flex: 1 1 auto;
  min-height: 0;
  height: var(--peel-stage-height, 320px);
  display: grid;
  place-items: center;
  padding: calc(var(--top-zone) + 0.75rem) var(--page-pad) calc(var(--bottom-zone) + 0.75rem);
  overflow: hidden;
  touch-action: none;
}

#peel-app .peel-frame {
  width: 100%;
  max-width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  min-height: 0;
  overflow: visible;
  touch-action: none;
}

#peel-app svg {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  background: transparent;
  overflow: visible;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
}

#peel-app .peel-toolbar {
  position: fixed;
  top: var(--top-zone);
  left: 2rem;
  z-index: 11;
  display: flex;
  align-items: center;
  box-sizing: border-box;
  padding: 0.2em 0;
  max-width: calc(100% - 4rem);
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-behavior: auto;
  user-select: none;
  touch-action: manipulation;
  opacity: 1;
  visibility: visible;
  transition:
    opacity 0.38s var(--ease-standard),
    visibility 0s linear 0s;
}

#peel-app .peel-toolbar-inner {
  display: flex;
  align-items: center;
  gap: var(--ui-gap);
  flex-wrap: nowrap;
}

#peel-app .peel-toolbar::-webkit-scrollbar {
  display: none;
}

#peel-app .peel-toolbar button,
#peel-app .peel-toolbar label.peel-file-trigger,
#peel-app .peel-toolbar label.peel-back-color {
  flex: 0 0 auto;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  border: 0;
  background: transparent;
  color: var(--text-primary);
  padding: 0;
  font-family: Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 2rem;
  font-weight: 400;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition:
    color 0.15s ease,
    text-shadow 0.2s ease,
    opacity 0.2s ease,
    transform 0.15s ease;
  touch-action: manipulation;
}

@media (hover: hover) {
  #peel-app button:hover,
  #peel-app label.peel-file-trigger:hover,
  #peel-app label.peel-back-color:hover {
    color: var(--text-strong);
  }
}

#peel-app button:active,
#peel-app label.peel-file-trigger:active,
#peel-app label.peel-back-color:active {
  transform: translateY(1px);
}

#peel-app button:focus,
#peel-app button:focus-visible,
#peel-app label.peel-file-trigger:focus,
#peel-app label.peel-file-trigger:focus-within,
#peel-app label.peel-back-color:focus-within {
  outline: none;
  box-shadow: none;
  color: var(--text-strong);
  text-shadow: 0 0 10px rgba(211, 194, 186, 0.22);
}

#peel-app button:disabled,
#peel-app button[aria-disabled="true"] {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

#peel-app label.peel-file-trigger,
#peel-app label.peel-back-color {
  position: relative;
}

#peel-app label.peel-back-color input[type="color"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  opacity: 0;
  cursor: pointer;
  border: 0;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  flex: none;
  min-width: 0;
  min-height: 0;
}

#peel-app label.peel-file-trigger input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* как #app-version */
#peel-app .peel-version-foot {
  position: fixed;
  bottom: 1rem;
  left: 1rem;
  z-index: 5;
  margin: 0;
  max-width: min(90vw, 28rem);
  font-family: Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 400;
  color: rgba(211, 194, 186, 0.35);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  opacity: 1;
  visibility: visible;
  transition:
    opacity 0.38s var(--ease-standard),
    visibility 0s linear 0s;
}

#peel-app .peel-version-foot a {
  color: inherit;
  text-decoration: none;
  pointer-events: auto;
  cursor: pointer;
}

#peel-app .peel-version-foot a:hover {
  color: rgba(211, 194, 186, 0.48);
}

/* как #status (видимое состояние) */
#peel-app .peel-hint {
  position: fixed;
  left: 50%;
  bottom: var(--bottom-zone);
  z-index: 10;
  max-width: min(44rem, calc(100% - 2rem));
  font-family: Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 2rem;
  line-height: 1.1;
  font-weight: 400;
  color: rgba(211, 194, 186, 0.48);
  text-align: center;
  white-space: nowrap;
  pointer-events: none;
  opacity: 1;
  visibility: visible;
  filter: blur(0);
  transform: translateX(-50%) translateY(0);
  transition:
    opacity 0.45s var(--ease-standard),
    filter 0.45s var(--ease-standard),
    transform 0.45s var(--ease-standard),
    visibility 0s linear 0s;
  will-change: opacity, filter, transform;
}

/* Report log: на body — иначе режется overflow:hidden у #peel-app */
#peel-report-log.peel-report-log.footer-link {
  position: fixed;
  bottom: 1rem;
  right: 1rem;
  z-index: 100000;
  display: none;
  font-family: Inter, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 400;
  color: rgba(211, 194, 186, 0.35);
  text-decoration: none;
  cursor: pointer;
  pointer-events: auto;
  opacity: 1;
  visibility: visible;
  transition:
    opacity 0.38s var(--ease-standard),
    visibility 0s linear 0s,
    color 0.2s ease;
}

#peel-report-log.peel-report-log.footer-link:hover {
  color: rgba(211, 194, 186, 0.48) !important;
}

#peel-report-log.peel-report-log.footer-link:focus,
#peel-report-log.peel-report-log.footer-link:focus-visible {
  outline: none;
  box-shadow: none;
}

#peel-report-log.peel-report-log.footer-link.peel-report-log--visible {
  display: inline-block;
}

/* Прятание вместе с Tab peel-chrome-hidden (видимая или ещё display:none до отчёта) */
#peel-report-log.peel-report-log.footer-link.peel-report-log--chrome-hidden {
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
  transition:
    opacity 0.38s var(--ease-standard),
    visibility 0s linear 0.38s,
    color 0.2s ease;
}

#peel-app .peel-hint.peel-hint--fade-out {
  opacity: 0;
  filter: blur(6px);
  transform: translateX(-50%) translateY(6px);
}

#peel-app .start-dot {
  fill: var(--text-strong);
  stroke: none;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
  opacity: 1;
}

#peel-app .peel-edge-hints {
  pointer-events: none;
}

#peel-app .peel-edge-hint {
  vector-effect: non-scaling-stroke;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

#peel-app .peel-edge-hint-mid {
  fill: rgba(211, 194, 186, 0.08);
  stroke: rgba(211, 194, 186, 0.28);
}

#peel-app .peel-edge-hint-path {
  fill: rgba(211, 194, 186, 0.06);
  stroke: rgba(211, 194, 186, 0.22);
  stroke-width: 1;
}

#peel-app .peel-edge-hint-strong {
  fill: var(--text-strong);
  stroke: rgba(211, 194, 186, 0.35);
  stroke-width: 1.25;
  filter: drop-shadow(0 0 8px rgba(211, 194, 186, 0.16));
}

#peel-app .peel-edge-hint.peel-edge-hint-can-fold {
  fill: var(--text-strong);
  stroke: #c9b8b0;
  stroke-width: 2;
  filter: drop-shadow(0 0 8px rgba(211, 194, 186, 0.28));
  opacity: 1;
}

#peel-app .peel-edge-hint.peel-edge-hint-blocked {
  fill: none;
  stroke: var(--text-strong);
  stroke-width: 2;
  filter: none;
  opacity: 1;
}

@media (max-width: 768px), (hover: none) {
  #peel-app .peel-toolbar {
    left: 0;
    right: 0;
    max-width: 100%;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scroll-behavior: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    touch-action: pan-x pinch-zoom;
  }

  #peel-app .peel-toolbar-inner {
    padding-left: 1rem;
    padding-right: 1rem;
    flex-shrink: 0;
    flex-wrap: nowrap;
  }

}

@media (max-width: 768px) {
  #peel-app .peel-toolbar button,
  #peel-app .peel-toolbar label.peel-file-trigger,
  #peel-app .peel-toolbar label.peel-back-color,
  #peel-app .peel-hint {
    font-size: 1.5rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  #peel-app *,
  #peel-app *::before,
  #peel-app *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  #peel-app .peel-hint.peel-hint--fade-out {
    filter: none !important;
    opacity: 1 !important;
    transform: translateX(-50%) translateY(0) !important;
  }

  #peel-report-log.peel-report-log.footer-link {
    transition-duration: 0.01ms !important;
  }
}

/* Tab toggles .peel-chrome-hidden from peel.js (toolbar + hints + footer) */
#peel-app.peel-chrome-hidden .peel-toolbar {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.38s var(--ease-standard),
    visibility 0s linear 0.38s;
}

#peel-app.peel-chrome-hidden #peel-status {
  opacity: 0;
  filter: blur(0);
  transform: translateX(-50%) translateY(8px);
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.42s var(--ease-standard),
    filter 0.42s var(--ease-standard),
    transform 0.42s var(--ease-standard),
    visibility 0s linear 0.42s;
}

#peel-app.peel-chrome-hidden .peel-version-foot {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.38s var(--ease-standard),
    visibility 0s linear 0.38s;
}



  
    
      
        Load image
        
      
      
        Back
        
      
      Reset
      Undo
      Export
    
  
  

  
    
      
    
  
  


</description>
		
	</item>
		
	</channel>
</rss>