Стилизуй на CSS параграфы в Twine чтобы были более...
Créé le : 10 août 2026
Répondu en utilisant GPT-5.6 Thinking par Chat01
Créé le : 10 août 2026
Répondu en utilisant GPT-5.6 Thinking par Chat01
Стилизуй на CSS параграфы в Twine чтобы были более цветными. Для tw-link лучше использовать black.
Да — если это Twine / Harlowe, можно сделать параграфы более живыми через мягкие цветные фоны, акцентные линии и разные оттенки для соседних абзацев. А tw-link оставить чёрным.
Вставь это в Story → Stylesheet:
css/* Основной текст */ tw-passage { color: #2b2b2b; font-size: 1.08em; line-height: 1.7; } /* Стилизация параграфов */ tw-passage p { padding: 14px 18px; margin: 16px 0; border-radius: 10px; border-left: 5px solid #ff7a90; background: linear-gradient( 135deg, rgba(255, 210, 220, 0.45), rgba(255, 240, 200, 0.35) ); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.06); transition: transform 0.2s ease, box-shadow 0.2s ease; } /* Разные цвета для абзацев */ tw-passage p:nth-of-type(3n + 1) { border-left-color: #ff6b81; background: linear-gradient( 135deg, rgba(255, 190, 205, 0.45), rgba(255, 225, 195, 0.3) ); } tw-passage p:nth-of-type(3n + 2) { border-left-color: #7d8cff; background: linear-gradient( 135deg, rgba(205, 215, 255, 0.45), rgba(225, 205, 255, 0.3) ); } tw-passage p:nth-of-type(3n + 3) { border-left-color: #52c7a5; background: linear-gradient( 135deg, rgba(195, 245, 225, 0.45), rgba(215, 240, 255, 0.3) ); } /* Небольшой эффект при наведении */ tw-passage p:hover { transform: translateY(-2px); box-shadow: 0 5px 14px rgba(0, 0, 0, 0.1); } /* Ссылки Twine */ tw-link { color: black; font-weight: 600; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; transition: opacity 0.15s ease, background-color 0.15s ease; } tw-link:hover { color: black; background-color: rgba(255, 220, 80, 0.65); opacity: 0.8; } /* Уже посещённые ссылки тоже чёрные */ tw-link.visited { color: black; }
Получится скорее цветной UI-карточный стиль, но без кислотных цветов: розовые, фиолетово-синие и мятные абзацы будут чередоваться, а ссылки останутся чёрными и хорошо заметными.
Если хочется именно более яркий визуальный стиль для визуальной новеллы — с цветным текстом, glow-эффектами и более красивыми tw-link как кнопками — я могу дать второй вариант CSS.
Придумай ещё цвет для tw-story а то blue выглядит очень плохо
Для tw-story я бы взял не чистый blue, а более спокойный фон, чтобы цветные параграфы не спорили с ним.
Лучше всего сюда подойдёт тёмный фиолетово-синий:
csstw-story { background-color: #25243a; }
Ещё хорошие варианты:
css/* Тёплый тёмно-фиолетовый */ background-color: #30263d; /* Глубокий серо-синий */ background-color: #293241; /* Тёмный сливовый */ background-color: #35283b; /* Мягкий тёмно-зелёный */ background-color: #263832; /* Светлый кремовый, если нужен светлый дизайн */ background-color: #f5efe6;
Для твоего текущего розово-мятно-фиолетового оформления я бы выбрал #30263d:
csstw-story { background: #30263d; }
Он достаточно тёмный, но не выглядит как стандартный синий экран, а пастельные карточки на нём будут хорошо выделяться.
Придумай как сделать выбор диалогов как кнопки
Можно сделать выборы как полноценные кнопки диалога: светлые карточки, чёрный текст, рамка и небольшой эффект нажатия. Для твоего тёмного tw-story это будет смотреться хорошо.
css/* Кнопки выбора */ tw-link { display: block; width: 100%; box-sizing: border-box; margin: 10px 0; padding: 14px 18px; color: black; background: #f4d6e8; border: 2px solid #d99bc1; border-radius: 12px; font-weight: 600; text-decoration: none; text-align: left; cursor: pointer; transition: transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease; } /* Наведение */ tw-link:hover { color: black; background: #f8c8e1; transform: translateX(5px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18); } /* Нажатие */ tw-link:active { transform: translateX(5px) scale(0.98); } /* Посещённые варианты тоже не становятся фиолетовыми */ tw-link.visited { color: black; }
В самом Twine можно тогда писать обычные варианты:
twine[[Спросить: «Что здесь произошло?»->Question]] [[Промолчать и осмотреть комнату->LookAround]] [[Уйти, пока не стало хуже->Leave]]
И получится примерно такой принцип:
text┌─────────────────────────────────────────┐ │ Спросить: «Что здесь произошло?» │ └─────────────────────────────────────────┘ ┌─────────────────────────────────────────┐ │ Промолчать и осмотреть комнату │ └─────────────────────────────────────────┘ ┌─────────────────────────────────────────┐ │ Уйти, пока не стало хуже │ └─────────────────────────────────────────┘
Ещё интереснее будет чередовать цвета вариантов, чтобы выбор выглядел живее:
csstw-link:nth-of-type(3n + 1) { background: #f4d6e8; border-color: #d99bc1; } tw-link:nth-of-type(3n + 2) { background: #d9e4ff; border-color: #9eafe0; } tw-link:nth-of-type(3n + 3) { background: #d5eee4; border-color: #91c9b3; } tw-link:nth-of-type(3n + 1):hover { background: #f7c6df; } tw-link:nth-of-type(3n + 2):hover { background: #cbd9ff; } tw-link:nth-of-type(3n + 3):hover { background: #c3e8d9; }
Я бы ещё добавил перед каждым вариантом маленький символ › — тогда они будут ощущаться именно как варианты ответа:
csstw-link::before { content: "›"; margin-right: 10px; font-size: 1.25em; font-weight: bold; }
Такой вариант особенно хорошо сочетается с твоим фоном #30263d: тёмный фон + пастельные кнопки + чёрный текст.
Сделай по-братски кнопку выхода из игры при нажатии на esc и чтобы она при наведении курсора "убегала" от него
Можно 😄 Сделаем так: при нажатии Esc появляется затемнение с кнопкой «Выйти из игры», но как только курсор приближается — кнопка прыгает в другое место.
В Story → JavaScript вставь:
javascript(function () { const overlay = document.createElement("div"); overlay.id = "exit-overlay"; const box = document.createElement("div"); box.id = "exit-box"; const title = document.createElement("div"); title.id = "exit-title"; title.textContent = "Точно хочешь выйти?"; const button = document.createElement("button"); button.id = "exit-button"; button.textContent = "Выйти из игры"; box.appendChild(title); box.appendChild(button); overlay.appendChild(box); document.body.appendChild(overlay); function showExit() { overlay.classList.add("active"); moveButton(); } function hideExit() { overlay.classList.remove("active"); } document.addEventListener("keydown", function (event) { if (event.key === "Escape") { if (overlay.classList.contains("active")) { hideExit(); } else { showExit(); } } }); function moveButton() { const padding = 30; const maxX = window.innerWidth - button.offsetWidth - padding; const maxY = window.innerHeight - button.offsetHeight - padding; const x = Math.max( padding, Math.random() * (maxX - padding) ); const y = Math.max( padding, Math.random() * (maxY - padding) ); button.style.left = x + "px"; button.style.top = y + "px"; } /* Убегает при наведении */ button.addEventListener("mouseenter", moveButton); /* И ещё раньше — когда мышь подходит близко */ document.addEventListener("mousemove", function (event) { if (!overlay.classList.contains("active")) return; const rect = button.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const distance = Math.hypot( event.clientX - centerX, event.clientY - centerY ); if (distance < 120) { moveButton(); } }); button.addEventListener("click", function () { /* * Браузеры обычно запрещают сайту закрывать вкладку, * если она не была открыта через JavaScript. */ window.close(); /* Если вкладка не закрылась — убираем игру */ setTimeout(function () { document.body.innerHTML = ` <div class="game-over-screen"> <h1>Игра закрыта.</h1> <p>Ну почти.</p> </div> `; }, 150); }); })();
А в Story → Stylesheet:
css/* Затемнение при Esc */ #exit-overlay { position: fixed; inset: 0; z-index: 999999; background: rgba(20, 15, 28, 0.88); backdrop-filter: blur(6px); opacity: 0; visibility: hidden; transition: opacity 0.25s ease, visibility 0.25s ease; } #exit-overlay.active { opacity: 1; visibility: visible; } /* Надпись */ #exit-title { position: fixed; top: 22%; left: 50%; transform: translateX(-50%); color: #f7eafa; font-size: 1.7em; font-weight: bold; text-align: center; pointer-events: none; } /* Та самая мерзкая кнопка */ #exit-button { position: fixed; padding: 15px 25px; color: black; background: #f4d6e8; border: 2px solid #d99bc1; border-radius: 14px; font-size: 1em; font-weight: bold; cursor: pointer; box-shadow: 0 5px 18px rgba(0, 0, 0, 0.25); transition: left 0.12s ease, top 0.12s ease, transform 0.12s ease, background 0.12s ease; } #exit-button:hover { color: black; background: #ffc4df; transform: rotate(-3deg) scale(1.05); } /* Фальшивый экран после выхода */ .game-over-screen { position: fixed; inset: 0; display: flex; flex-direction: column; justify-content: center; align-items: center; background: #30263d; color: #f7eafa; font-family: inherit; text-align: center; } .game-over-screen h1 { margin-bottom: 5px; } .game-over-screen p { opacity: 0.65; }
Самое забавное тут то, что кнопка начинает убегать ещё до наведения, когда курсор оказывается ближе чем на 120px.
Если хочешь сделать её ещё более издевательской, поменяй:
javascriptif (distance < 120)
на:
javascriptif (distance < 200)
Тогда поймать её будет практически невозможно.
И да: настоящее window.close() браузер обычно блокирует для обычной вкладки. Поэтому я добавил запасной вариант — после успешного клика игра просто превращается в экран «Игра закрыта. Ну почти.».
Поменяй вместо затемнения игры, эффект фокуса.
Да, лучше сделать эффект расфокуса игры, будто камера фокусируется на меню выхода. Вместо затемнения фон будет просто размываться.
Замени стили #exit-overlay на эти:
css#exit-overlay { position: fixed; inset: 0; z-index: 999999; /* Фон прозрачный — никакого затемнения */ background: rgba(255, 255, 255, 0.01); /* Эффект расфокуса игры */ backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); opacity: 0; visibility: hidden; transition: opacity 0.3s ease, visibility 0.3s ease, backdrop-filter 0.3s ease; } #exit-overlay.active { opacity: 1; visibility: visible; }
Я бы ещё сделал сам текст немного более «в фокусе», чтобы он визуально выступал над размытой игрой:
css#exit-title { position: fixed; top: 22%; left: 50%; transform: translateX(-50%); color: white; font-size: 1.7em; font-weight: bold; text-align: center; text-shadow: 0 2px 5px rgba(0, 0, 0, 0.4), 0 0 18px rgba(255, 255, 255, 0.25); pointer-events: none; }
А если хочется прям эффекта глубины резкости, можно сделать чуть интереснее:
css#exit-overlay { position: fixed; inset: 0; z-index: 999999; background: transparent; backdrop-filter: blur(10px) saturate(0.75); -webkit-backdrop-filter: blur(10px) saturate(0.75); opacity: 0; visibility: hidden; transition: opacity 0.35s ease, visibility 0.35s ease; } #exit-overlay.active { opacity: 1; visibility: visible; }
Тогда при Esc сама игра становится слегка размытой и менее насыщенной, а надпись и убегающая кнопка остаются идеально резкими. По-моему, для такого меню это выглядит намного приятнее, чем просто чёрное затемнение.
Лучше, сделай чтобы она "уплывала" не быстро и скажем вокруг курсора была
Да, так будет приятнее: не телепортировать кнопку, а сделать зону отталкивания вокруг курсора. Когда мышь подходит близко, кнопка плавно «уплывает» от неё, а не скачет по экрану.
В JavaScript замени старые moveButton() и обработчик mousemove на это:
javascriptlet buttonX = window.innerWidth / 2; let buttonY = window.innerHeight / 2; let targetX = buttonX; let targetY = buttonY; const escapeRadius = 180; // Радиус вокруг курсора const pushStrength = 7; // Насколько сильно кнопка отплывает const smoothness = 0.045; // Чем меньше — тем медленнее движение function resetButtonPosition() { buttonX = window.innerWidth / 2 - button.offsetWidth / 2; buttonY = window.innerHeight * 0.55; targetX = buttonX; targetY = buttonY; button.style.left = buttonX + "px"; button.style.top = buttonY + "px"; } /* Кнопка плавно отталкивается от курсора */ document.addEventListener("mousemove", function (event) { if (!overlay.classList.contains("active")) return; const rect = button.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const dx = centerX - event.clientX; const dy = centerY - event.clientY; const distance = Math.hypot(dx, dy); /* Если курсор вошёл в "зону страха" кнопки */ if (distance < escapeRadius) { /* * Чем ближе курсор — * тем сильнее кнопка отплывает. */ const force = (escapeRadius - distance) / escapeRadius; const safeDistance = Math.max(distance, 1); const directionX = dx / safeDistance; const directionY = dy / safeDistance; targetX += directionX * pushStrength * force; targetY += directionY * pushStrength * force; } }); /* Плавная анимация */ function animateButton() { buttonX += (targetX - buttonX) * smoothness; buttonY += (targetY - buttonY) * smoothness; /* Не даём кнопке уплыть за экран */ const padding = 25; const maxX = window.innerWidth - button.offsetWidth - padding; const maxY = window.innerHeight - button.offsetHeight - padding; buttonX = Math.max( padding, Math.min(buttonX, maxX) ); buttonY = Math.max( padding, Math.min(buttonY, maxY) ); targetX = Math.max( padding, Math.min(targetX, maxX) ); targetY = Math.max( padding, Math.min(targetY, maxY) ); button.style.left = buttonX + "px"; button.style.top = buttonY + "px"; requestAnimationFrame(animateButton); } animateButton();
И функцию showExit() поменяй на:
javascriptfunction showExit() { overlay.classList.add("active"); setTimeout(function () { resetButtonPosition(); }, 20); }
Также удали старое:
javascriptbutton.addEventListener("mouseenter", moveButton);
и старую функцию:
javascriptfunction moveButton() { ... }
В CSS у кнопки лучше убрать анимацию left и top, потому что теперь плавность контролирует JavaScript:
css#exit-button { position: fixed; padding: 15px 25px; color: black; background: #f4d6e8; border: 2px solid #d99bc1; border-radius: 14px; font-size: 1em; font-weight: bold; cursor: pointer; box-shadow: 0 5px 18px rgba(0, 0, 0, 0.25); transition: transform 0.2s ease, background 0.2s ease; }
Теперь механика получается такая: курсор имеет вокруг себя невидимый круг примерно 180 px, и когда кнопка оказывается внутри него, она начинает медленно отплывать в противоположную сторону.
Можно настроить характер:
javascriptconst escapeRadius = 180; const pushStrength = 7; const smoothness = 0.045;
Например, для совсем ленивой, раздражающей кнопки:
javascriptconst escapeRadius = 150; const pushStrength = 4; const smoothness = 0.025;
Она будет такая: «ладно-ладно, я ухожу…» и очень медленно отплывать от курсора. 😄
Можешь просто по братски соединить чтобы было всё ок и плавное "уплывание" кнопки выхода вокруг курсора и эффект фокуса
Да 😄 Вот уже цельный вариант, чтобы ничего не собирать по кусочкам: Esc открывает меню, игра плавно расфокусируется, а кнопка выхода мягко уплывает от курсора, без телепортаций.
javascript(function () { /* ========================= СОЗДАЁМ МЕНЮ ВЫХОДА ========================= */ const overlay = document.createElement("div"); overlay.id = "exit-overlay"; const title = document.createElement("div"); title.id = "exit-title"; title.textContent = "Точно хочешь выйти?"; const button = document.createElement("button"); button.id = "exit-button"; button.textContent = "Выйти из игры"; overlay.appendChild(title); overlay.appendChild(button); document.body.appendChild(overlay); /* ========================= НАСТРОЙКИ ДВИЖЕНИЯ ========================= */ // Насколько далеко кнопка "чувствует" курсор const escapeRadius = 190; // Сила отталкивания const pushStrength = 1.8; // Плавность движения // меньше = медленнее и плавнее const smoothness = 0.075; // Отступ от краёв экрана const screenPadding = 30; let buttonX = 0; let buttonY = 0; let targetX = 0; let targetY = 0; let mouseX = -1000; let mouseY = -1000; let menuOpen = false; /* ========================= НАЧАЛЬНАЯ ПОЗИЦИЯ ========================= */ function resetButtonPosition() { buttonX = window.innerWidth / 2 - button.offsetWidth / 2; buttonY = window.innerHeight * 0.57; targetX = buttonX; targetY = buttonY; button.style.left = buttonX + "px"; button.style.top = buttonY + "px"; } /* ========================= ОТКРЫТИЕ / ЗАКРЫТИЕ ========================= */ function showExitMenu() { menuOpen = true; overlay.classList.add("active"); requestAnimationFrame(function () { resetButtonPosition(); }); } function hideExitMenu() { menuOpen = false; overlay.classList.remove("active"); // Чтобы при следующем открытии // старая позиция мыши не пугала кнопку mouseX = -1000; mouseY = -1000; } /* ESC открывает и закрывает меню */ document.addEventListener("keydown", function (event) { if (event.key === "Escape") { event.preventDefault(); if (menuOpen) { hideExitMenu(); } else { showExitMenu(); } } }); /* ========================= СЛЕДИМ ЗА КУРСОРОМ ========================= */ document.addEventListener("mousemove", function (event) { mouseX = event.clientX; mouseY = event.clientY; }); /* ========================= ПЛАВНОЕ "УПЛЫВАНИЕ" ========================= */ function animate() { if (menuOpen) { const centerX = buttonX + button.offsetWidth / 2; const centerY = buttonY + button.offsetHeight / 2; /* Расстояние между курсором и кнопкой */ const dx = centerX - mouseX; const dy = centerY - mouseY; const distance = Math.hypot(dx, dy); /* * Если курсор входит в невидимый круг * вокруг кнопки — она начинает отплывать. */ if (distance < escapeRadius) { const safeDistance = Math.max(distance, 1); const directionX = dx / safeDistance; const directionY = dy / safeDistance; /* * Чем курсор ближе, * тем сильнее отталкивание. */ const force = 1 - distance / escapeRadius; targetX += directionX * pushStrength * force * 12; targetY += directionY * pushStrength * force * 12; } /* ========================= НЕ ДАЁМ УПЛЫТЬ ЗА ЭКРАН ========================= */ const maxX = window.innerWidth - button.offsetWidth - screenPadding; const maxY = window.innerHeight - button.offsetHeight - screenPadding; targetX = Math.max( screenPadding, Math.min(targetX, maxX) ); targetY = Math.max( screenPadding, Math.min(targetY, maxY) ); /* ========================= ПЛАВНО ДОГОНЯЕМ ЦЕЛЬ ========================= */ buttonX += (targetX - buttonX) * smoothness; buttonY += (targetY - buttonY) * smoothness; button.style.left = buttonX + "px"; button.style.top = buttonY + "px"; } requestAnimationFrame(animate); } animate(); /* ========================= ИЗМЕНЕНИЕ РАЗМЕРА ОКНА ========================= */ window.addEventListener("resize", function () { if (menuOpen) { resetButtonPosition(); } }); /* ========================= НАЖАТИЕ НА КНОПКУ ========================= */ button.addEventListener("click", function () { window.close(); /* * Браузер обычно не разрешает сайту * самостоятельно закрывать обычную вкладку. * Поэтому делаем запасной экран. */ setTimeout(function () { document.body.innerHTML = ` <div class="game-over-screen"> <h1>Игра закрыта.</h1> <p>Ну почти.</p> </div> `; }, 150); }); })();
css/* ========================= ЭФФЕКТ ФОКУСА ========================= */ #exit-overlay { position: fixed; inset: 0; z-index: 999999; /* * Практически прозрачный фон. * Затемнения нет. */ background: rgba(255, 255, 255, 0.01); /* * Игра сзади становится * расфокусированной. */ backdrop-filter: blur(9px) saturate(0.75); -webkit-backdrop-filter: blur(9px) saturate(0.75); opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 0.35s ease, visibility 0.35s ease; } #exit-overlay.active { opacity: 1; visibility: visible; pointer-events: auto; } /* ========================= ЗАГОЛОВОК ========================= */ #exit-title { position: fixed; top: 25%; left: 50%; transform: translateX(-50%); color: white; font-size: 1.8em; font-weight: bold; text-align: center; text-shadow: 0 2px 6px rgba(0, 0, 0, 0.45), 0 0 20px rgba(255, 255, 255, 0.15); pointer-events: none; user-select: none; } /* ========================= КНОПКА ВЫХОДА ========================= */ #exit-button { position: fixed; padding: 15px 26px; color: black; background: #f4d6e8; border: 2px solid #d99bc1; border-radius: 14px; font-family: inherit; font-size: 1em; font-weight: 600; cursor: pointer; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25); /* * left/top здесь специально * НЕ анимируем через CSS. * * Плавность делает JavaScript, * поэтому движение получается * гораздо естественнее. */ transition: background 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease; } #exit-button:hover { color: black; background: #f8c5df; box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3); transform: scale(1.03); } #exit-button:active { transform: scale(0.97); } /* ========================= ЭКРАН "ВЫХОДА" ========================= */ .game-over-screen { position: fixed; inset: 0; display: flex; flex-direction: column; justify-content: center; align-items: center; background: #30263d; color: #f7eafa; font-family: inherit; text-align: center; } .game-over-screen h1 { margin-bottom: 5px; } .game-over-screen p { opacity: 0.65; }
Главное здесь — кнопка теперь вообще не прыгает. У курсора есть невидимая зона примерно 190px, и когда он приближается, кнопка начинает как будто физически от него отплывать.
Если хочется ещё более ленивое и издевательское движение, поменяй только:
javascriptconst escapeRadius = 210; const pushStrength = 1.3; const smoothness = 0.045;
Тогда она будет буквально медленно ускользать из-под мышки, а не панически убегать.
Оформи пж по братски формы для параграфов
Конечно 😄 Я бы сделал параграфы не просто цветными прямоугольниками, а с разными мягкими формами, чтобы текст выглядел как элементы визуальной новеллы.
Попробуй такой вариант в Story → Stylesheet:
css/* ========================= ОБЩИЙ СТИЛЬ ПАРАГРАФОВ ========================= */ tw-passage p { position: relative; margin: 18px 0; padding: 16px 20px; color: #2b2530; background: #f4d6e8; border: 2px solid rgba(255, 255, 255, 0.35); line-height: 1.65; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.14); transition: transform 0.25s ease, box-shadow 0.25s ease; } /* ========================= 1 — МЯГКАЯ КАРТОЧКА ========================= */ tw-passage p:nth-of-type(4n + 1) { background: #f4d6e8; border-radius: 22px 8px 22px 8px; } /* ========================= 2 — СРЕЗАННЫЕ УГЛЫ ========================= */ tw-passage p:nth-of-type(4n + 2) { background: #d9e4ff; border-radius: 8px; clip-path: polygon( 14px 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%, 0 14px ); } /* ========================= 3 — ПОЛУКРУГЛАЯ ФОРМА ========================= */ tw-passage p:nth-of-type(4n + 3) { background: #d5eee4; border-radius: 26px 26px 8px 26px; } /* ========================= 4 — ДИАЛОГОВАЯ КАРТОЧКА ========================= */ tw-passage p:nth-of-type(4n + 4) { background: #f4e4bd; border-radius: 12px 24px 24px 24px; } /* ========================= ЛЁГКИЙ ЭФФЕКТ НАВЕДЕНИЯ ========================= */ tw-passage p:hover { transform: translateY(-2px) scale(1.005); box-shadow: 0 9px 24px rgba(0, 0, 0, 0.18); }
Мне особенно нравится форма с асимметричными скруглениями:
cssborder-radius: 22px 8px 22px 8px;
Она сразу убирает ощущение обычного HTML-блока.
Можно ещё добавить слева маленькую декоративную метку:
csstw-passage p::before { content: ""; position: absolute; left: -5px; top: 18px; width: 8px; height: 28px; background: rgba(255, 255, 255, 0.8); border-radius: 20px; }
А если хочешь именно диалоговые облачка, можно сделать хвостик:
csstw-passage p.dialogue { border-radius: 20px; } tw-passage p.dialogue::after { content: ""; position: absolute; left: 25px; bottom: -10px; width: 20px; height: 20px; background: inherit; transform: rotate(45deg); border-radius: 3px; }
Тогда визуально получится что-то вроде:
text╭──────────────────────────────╮ │ — Ты уверен, что нам сюда? │ │ │ │ Кажется, это плохая идея. │ ╰───────◇──────────────────────╯
Для твоего тёмного #30263d я бы оставил пастельные карточки + необычную форму + небольшую тень — это будет гораздо приятнее, чем куча ярких цветов без структуры.