개발을 위한 전체 프로젝트 구조 설정

프로젝트 폴더 구조 정의




 src 하위에 아래와 같은 폴더를 생성하여 전체적인 구조를 설정 후 작업한다.
@types, a11y,common, componets, data-provider, hooks, locales, Providers, routes, store, utils

각각의 폴더를 만들어서 구분함으로써 나중에 유지 보수 적인 측면이나 여러 모로 용도가 분류 되어야 개발 할때 좀 더 명확하다.

프로젝트를 진행 하면서 하나씩 채워 나갈 예정이다.

먼저 최초의 진입점 화면 부터 구현해 보자. 화면을 구현하기 앞서서 기본 css 파일을 먼저 작성 하겠다.

client 최상단 폴더에 mobile.css, style.css 파일을 먼저 작성한다.

mobile.css


mobile.css 내용이다.

.hover-button.active {
  display: block;
  visibility: visible;
}

.nav-close-button {
  margin-left: 8px;
}

.nav {
  position: fixed;
  z-index: 64;
  top: 0;

  /* max-width: 260px; */

  bottom: 0;
  opacity: 0;
}

.nav.active {
  position: relative;
  left: 0;
  opacity: 1;
}

.nav-mask.active {
  opacity: 0;
  pointer-events: auto;
}

@media (max-width: 767px) {
  .nav {
    width: calc(100% - 10px)  ;
    transition: all 0.15s;
  }
  .nav-mask {
    position: fixed;
    z-index: 63;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background-color: rgba(7, 7, 7, 0.4);
    padding-left: 420px;
    padding-top: 12px;
    opacity: 0;
    transition: all 0.5s;
    pointer-events: none;
  }

  .nav-open-button {
    opacity: 0;
  }

  .nav-mask.active {
    opacity: 1;
    pointer-events: auto;
  }

  .nav.active {
    position: fixed;
  }
}

@media (min-width: 1024px) {
  .switch-container {
    display: none;
  }
}


  .switch-result {
    display: block !important;
    visibility: visible;
  }

@media (max-width: 1024px) {
  /* .sibling-switch {
        left: 114px;
        top: unset;
        bottom: 4px;
        visibility: visible;
        z-index: 2;
    } */
  .sibling-switch {
    display: none;
  }

  .hover-button {
    display: block;
    visibility: visible;
  }
}

@media (max-width: 767px) {
  .input-panel-button {
    border: 0;
  }

  .input-panel-button svg {
    width: 16px;
    height: 16px;
  }

  .input-panel {
  }

  .nav-open-button
  {
    visibility: hidden;
  }
}

.hide-scrollbar {
  /* Hide scrollbar for Chrome, Safari, and Opera */
  scrollbar-width: none; /* For Firefox */
  -ms-overflow-style: none; /* For Internet Explorer and Edge */
}

.hide-scrollbar::-webkit-scrollbar {
  display: none; /* For WebKit browsers */
}

.gemini-gradient {
  /* Adjust the colors and positioning as necessary to match the image */
  background-image: radial-gradient(circle at center, #0000ff, #87cefa, #ffffff);
  /* More styling for demonstration purposes */
  border-radius: 50%;
  height: 100px;
  width: 100px;
}

@media (max-width: 767px) {
  .sidenav {
    /* width: calc(100% - 10px)  ; */
    transition: all 0.15s;
    position: fixed;
    z-index: 66;
    top: 0;
    max-width: 320px;

    /* max-width: 260px; */

    bottom: 0;
    right: 0
    /* opacity: 0; */
  }
  .sidenav-mask {
    position: fixed;
    z-index: 65;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background-color: rgba(86, 88, 105, 0.75);
    padding-left: 420px;
    padding-top: 12px;
    opacity: 0;
    transition: all 0.5s;
    pointer-events: none;
  }

  .sidenav-mask.active {
    opacity: 1;
    pointer-events: auto;
  }

  .sidenav.active {
    position: fixed;
  }
}

@keyframes tuning {
  0% { transform: rotate(30deg); }
  25% { transform: rotate(110deg); }
  50% { transform: rotate(-40deg); }
  75% { transform: rotate(80deg) }
  100% { transform: rotate(30deg) }
}

.rotate {
  animation: tuning 2.1s 1;
}

@-webkit-keyframes slideUpAndFade {
  0% {
    opacity:0;
    -webkit-transform:translateY(2px);
    transform:translateY(2px)
  }
  to {
    opacity:1;
    -webkit-transform:translateY(0);
    transform:translateY(0)
  }
}
@keyframes slideUpAndFade {
  0% {
    opacity:0;
    -webkit-transform:translateY(2px);
    transform:translateY(2px)
  }
  to {
    opacity:1;
    -webkit-transform:translateY(0);
    transform:translateY(0)
  }
}
.radix-side-bottom\:animate-slideUpAndFade[data-side=bottom] {
  -webkit-animation:slideUpAndFade .4s cubic-bezier(.16,1,.3,1);
  animation:slideUpAndFade .4s cubic-bezier(.16,1,.3,1)
}
@-webkit-keyframes slideRightAndFade {
  0% {
    opacity:0;
    -webkit-transform:translateX(-2px);
    transform:translateX(-2px)
  }
  to {
    opacity:1;
    -webkit-transform:translateX(0);
    transform:translateX(0)
  }
}
@keyframes slideRightAndFade {
  0% {
    opacity:0;
    -webkit-transform:translateX(-2px);
    transform:translateX(-2px)
  }
  to {
    opacity:1;
    -webkit-transform:translateX(0);
    transform:translateX(0)
  }
}
.radix-side-left\:animate-slideRightAndFade[data-side=left] {
  -webkit-animation:slideRightAndFade .4s cubic-bezier(.16,1,.3,1);
  animation:slideRightAndFade .4s cubic-bezier(.16,1,.3,1)
}
@keyframes slideLeftAndFade {
  0% {
    opacity:0;
    -webkit-transform:translateX(2px);
    transform:translateX(2px)
  }
  to {
    opacity:1;
    -webkit-transform:translateX(0);
    transform:translateX(0)
  }
}
.radix-side-right\:animate-slideLeftAndFade[data-side=right] {
  -webkit-animation:slideLeftAndFade .4s cubic-bezier(.16,1,.3,1);
  animation:slideLeftAndFade .4s cubic-bezier(.16,1,.3,1)
}
@keyframes slideDownAndFade {
  0% {
    opacity:0;
    -webkit-transform:translateY(-2px);
    transform:translateY(-2px)
  }
  to {
    opacity:1;
    -webkit-transform:translateY(0);
    transform:translateY(0)
  }
}
.radix-side-top\:animate-slideDownAndFade[data-side=top] {
  -webkit-animation:slideDownAndFade .4s cubic-bezier(.16,1,.3,1);
  animation:slideDownAndFade .4s cubic-bezier(.16,1,.3,1)
}

.azure-bg-color {
  background: linear-gradient(0.375turn, #61bde2, #4389d0);
}

@keyframes slowPulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.7;
  }
}

.slow-pulse {
  animation: slowPulse 2.5s ease-in-out infinite;
}

.scrollbar-gutter-stable {
  scrollbar-gutter: stable;
}

/* Styles for Chrome scrollbar */
.chrome-scrollbar::-webkit-scrollbar {
  width: 12px;  /* Increase the width of the scrollbar */
}

.chrome-scrollbar::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, 0.2);  /* Color of the scroll thumb */
  border-radius: 6px;  /* Rounded corners on the scroll thumb */
  border: 2px solid transparent;  /* Creates padding around scroll thumb */
  background-clip: padding-box;  /* Prevents background color from leaking outside the border */
}

.chrome-scrollbar::-webkit-scrollbar-thumb:hover {
  background-color: rgba(0, 0, 0, 0.3);  /* Darker color when hovering */
}

.chrome-scrollbar::-webkit-scrollbar-track {
  background-color: transparent;  /* Color of the tracking area */
}

.sp-preview-container {
  @apply flex h-full w-full grow flex-col justify-center;
}

.sp-preview {
  @apply flex h-full w-full grow flex-col justify-center;
}

.sp-preview-iframe {
  @apply grow;
}

.sp-wrapper {
  @apply flex h-full w-full grow flex-col justify-center;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 30%, 50%, 70%, 90% { transform: translateX(-3px); }
  20%, 40%, 60%, 80% { transform: translateX(3px); }
}

.shake {
  animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both;
}

div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"] {
  scrollbar-gutter: stable !important;
  background-color: rgba(205, 205, 205, 0.66) !important;
}

div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"]::-webkit-scrollbar {
  width: 12px !important;
}

div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"]::-webkit-scrollbar-thumb {
  background-color: rgba(56, 56, 56) !important;
  border-radius: 6px !important;
  border: 2px solid transparent !important;
  background-clip: padding-box !important;
}

div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"]::-webkit-scrollbar-track {
  background-color: transparent !important;
}

.cm-content:focus {
  outline: none !important;
}

p.whitespace-pre-wrap a, li a {
  color: #0066cc;
  text-decoration: underline;
  font-weight: bold;
}

.dark p.whitespace-pre-wrap a, .dark li a {
  color: #52a0ff;
}

 mobile.css 파일은 주로 모바일 환경 및 반응형 디자인을 위한 CSS 규칙들을 담고 있습니다. 또한, 특정 UI 요소의 동작 및 애니메이션, 스크롤바 커스터마이징, 그리고 Radix UI 컴포넌트와의 상호작용에 대한 스타일도 포함하고 있습니다.


1. 기본 UI 요소 및 활성화 상태 (Active States)

  • .hover-button.active: hover-button 클래스를 가진 요소가 active 클래스도 가질 때, 해당 요소를 보이게(display: block; visibility: visible;) 합니다. 이는 평소에는 숨겨져 있다가 특정 조건(예: 클릭)에서 나타나는 버튼에 사용될 수 있습니다.
  • .nav-close-button: 내비게이션 닫기 버튼에 **왼쪽 여백(margin-left: 8px)**을 줍니다.

2. 내비게이션(.nav) 및 마스크(.nav-mask) 스타일

이 섹션은 주로 모바일 환경에서 사용되는 사이드 내비게이션 바와 그 위에 겹쳐지는 **오버레이(마스크)**에 대한 스타일을 정의합니다.

  • .nav:
    • position: fixed; z-index: 64; top: 0; bottom: 0;: 화면에 고정되고, 다른 요소들 위에 나타나며(높은 z-index), 화면 상단과 하단에 맞춰집니다.
    • opacity: 0;: 기본적으로는 투명하게(숨겨진 상태) 설정되어 있습니다.
    • max-width: 260px;는 주석 처리되어 있습니다.
  • .nav.active: .nav 요소가 active 클래스를 가질 때 (활성화될 때):
    • position: relative; left: 0; opacity: 1;: position: relative로 변경되고 왼쪽으로 0px 이동하며, 불투명하게(보이게) 변합니다. (참고: @media (max-width: 767px) 미디어 쿼리 안에서 position: fixed로 재정의됩니다. 이는 모바일에서만 고정 위치로 작동하게 하는 것으로 보입니다.)
  • .nav-mask.active: 내비게이션 마스크가 active 클래스를 가질 때:
    • opacity: 0; pointer-events: auto;: 투명하게 되지만, pointer-events: auto로 설정되어 클릭 이벤트를 받을 수 있게 합니다. (이 부분은 뒤의 미디어 쿼리와 함께 봐야 명확해집니다. 아래 설명 참고.)

3. 미디어 쿼리: max-width: 767px (모바일/태블릿 세로 모드)

이 규칙들은 화면 너비가 767px 이하일 때 적용됩니다. 주로 모바일 기기를 대상으로 합니다.

  • .nav:
    • width: calc(100% - 10px);: 화면 너비에서 10px을 뺀 너비를 가집니다.
    • transition: all 0.15s;: 모든 속성 변경에 0.15초의 전환 효과를 줍니다.
  • .nav-mask:
    • position: fixed; z-index: 63; left: 0; right: 0; top: 0; bottom: 0;: 화면 전체를 덮도록 고정됩니다.
    • background-color: rgba(7, 7, 7, 0.4);: 어두운 반투명 배경색을 가집니다.
    • padding-left: 420px; padding-top: 12px;: 패딩이 적용되어 있습니다. (이 패딩은 마스크 자체의 콘텐츠를 밀어내는 용도일 수 있습니다.)
    • opacity: 0; transition: all 0.5s; pointer-events: none;: 기본적으로 투명하고, 0.5초 전환 효과를 가지며, 클릭 이벤트를 받지 못하게 합니다.
  • .nav-open-button: 내비게이션 열기 버튼을 투명하게(숨김) 만듭니다. (아마도 이 버튼은 데스크톱에서만 보이고 모바일에서는 다른 방식으로 내비게이션을 열게 하는 용도일 수 있습니다.)
  • .nav-mask.active: 마스크가 active일 때:
    • opacity: 1; pointer-events: auto;: 불투명하게(보이게) 변하며, 클릭 이벤트를 받을 수 있게 됩니다. (일반적으로 사이드바 외부를 클릭하여 사이드바를 닫는 기능에 사용됩니다.)
  • .nav.active: 내비게이션이 active일 때 **고정(position: fixed)**되도록 재정의합니다. (이는 데스크톱에서는 position: relative일 수 있음을 시사합니다.)

4. 미디어 쿼리: min-width: 1024px (데스크톱/큰 태블릿)

  • .switch-container: 특정 컨테이너를 숨깁니다(display: none).

5. 미디어 쿼리: max-width: 1024px (중간 크기 이하)

  • .sibling-switch: display: none;으로 숨깁니다. (주석 처리된 다른 스타일들은 이 요소를 모바일 하단에 고정하는 시도였던 것으로 보입니다.)
  • .hover-button: display: block; visibility: visible;로 설정하여 항상 보이게 합니다.

6. 미디어 쿼리: max-width: 767px (입력 패널 버튼)

  • .input-panel-button: 테두리를 제거하고(border: 0;), 내부 SVG 아이콘의 크기를 16px로 조정합니다.
  • .nav-open-button: 숨깁니다(visibility: hidden;).

7. 스크롤바 커스터마이징

다양한 브라우저에서 스크롤바를 숨기거나 커스터마이징하는 규칙입니다.

  • .hide-scrollbar:
    • scrollbar-width: none;: Firefox에서 스크롤바를 숨깁니다.
    • -ms-overflow-style: none;: IE 및 Edge에서 스크롤바를 숨깁니다.
  • .hide-scrollbar::-webkit-scrollbar: WebKit 기반 브라우저(Chrome, Safari 등)에서 스크롤바를 숨깁니다.
  • .chrome-scrollbar: WebKit 기반 브라우저의 스크롤바를 커스터마이징합니다.
    • ::-webkit-scrollbar: 스크롤바 너비를 12px로 설정합니다.
    • ::-webkit-scrollbar-thumb: 스크롤바 핸들(thumb)의 색상, 둥근 모서리, 패딩을 설정합니다.
    • ::-webkit-scrollbar-thumb:hover: 핸들에 마우스를 올렸을 때 색상을 어둡게 합니다.
    • ::-webkit-scrollbar-track: 스크롤바 트랙(track)을 투명하게 설정합니다.

8. 제미니 그라데이션(.gemini-gradient)

  • background-image: radial-gradient(circle at center, #0000ff, #87cefa, #ffffff);: 파란색 계열의 원형 그라데이션 배경을 적용합니다.
  • border-radius: 50%; height: 100px; width: 100px;: 요소를 원형으로 만들고 크기를 100x100px로 설정합니다. (아마도 로고나 아이콘에 사용될 수 있습니다.)

9. 사이드 내비게이션(.sidenav) 및 마스크(.sidenav-mask) (모바일)

이 섹션은 .nav와 유사하지만 right: 0으로 설정되어 오른쪽에서 나타나는 사이드바를 정의하는 것으로 보입니다.

  • @media (max-width: 767px): 화면 너비가 767px 이하일 때 적용됩니다.
    • .sidenav:
      • width: calc(100% - 10px); transition: all 0.15s;: .nav와 유사한 너비 및 전환 효과를 가집니다.
      • position: fixed; z-index: 66; top: 0; bottom: 0; right: 0;: 화면 우측에 고정되고, 다른 요소들 위에 나타나며(더 높은 z-index), 화면 상단과 하단에 맞춰집니다.
      • max-width: 320px;: 최대 너비를 320px로 제한합니다.
    • .sidenav-mask:
      • position: fixed; z-index: 65; left: 0; right: 0; top: 0; bottom: 0;: 화면 전체를 덮도록 고정됩니다.
      • background-color: rgba(86, 88, 105, 0.75);: 어두운 반투명 회색 배경색을 가집니다.
      • opacity: 0; transition: all 0.5s; pointer-events: none;: 기본적으로 투명하고, 0.5초 전환 효과를 가지며, 클릭 이벤트를 받지 못하게 합니다.
    • .sidenav-mask.active: 마스크가 active일 때 불투명하게(보이게) 변하며, 클릭 이벤트를 받을 수 있게 됩니다.
    • .sidenav.active: 사이드바가 active일 때 **고정(position: fixed)**되도록 재정의합니다.

10. 애니메이션 (@keyframes)

다양한 UI 요소에 적용될 수 있는 CSS 애니메이션 정의입니다.

  • @keyframes tuning:
    • 요소가 회전하는 애니메이션을 정의합니다. 0%, 25%, 50%, 75%, 100% 지점에서 다른 각도로 회전합니다.
  • .rotate: tuning 애니메이션을 2.1초 동안 한 번 실행합니다.
  • @keyframes slideUpAndFade, slideRightAndFade, slideLeftAndFade, slideDownAndFade:
    • Radix UI 컴포넌트(아마도 팝오버, 툴팁 등)에서 사용되는 것으로 보이는 애니메이션입니다. 요소가 나타날 때 특정 방향에서 미끄러지듯이 나타나면서 서서히 불투명해지는 효과를 줍니다.
    • -webkit- 접두사는 구형 WebKit 브라우저를 위한 호환성을 제공합니다.
  • .radix-side-bottom\:animate-slideUpAndFade[data-side=bottom], radix-side-left\:animate-slideRightAndFade[data-side=left], radix-side-right\:animate-slideLeftAndFade[data-side=right], radix-side-top\:animate-slideDownAndFade[data-side=top]:
    • Radix UI의 특정 data-side 속성을 가진 요소에 해당하는 slide 애니메이션을 0.4초 동안 적용합니다. cubic-bezier(.16,1,.3,1)는 애니메이션의 가속/감속 곡선을 정의합니다.
  • @keyframes slowPulse:
    • 요소의 opacity를 1에서 0.7로, 다시 1로 변경하여 느리게 깜빡이는(펄스) 효과를 만듭니다.
  • .slow-pulse: slowPulse 애니메이션을 2.5초 동안 무한히 반복합니다.
  • @keyframes shake:
    • 요소가 좌우로 빠르게 흔들리는 "흔들림" 애니메이션을 정의합니다.
  • .shake: shake 애니메이션을 0.5초 동안 적용합니다.

11. 스크롤바 여백 및 Radix UI 탭 패널 스크롤바

  • .scrollbar-gutter-stable: 스크롤바가 나타날 공간을 미리 확보하여 콘텐츠가 움직이는 것을 방지합니다.
  • div[role="tabpanel"][data-state="active"][data-orientation="horizontal"][aria-labelledby^="radix-"][id^="radix-"][id$="-content-preview"]:
    • Radix UI의 특정 tabpanel 역할과 data 속성을 가진 요소(아마도 가로 방향 활성 미리보기 탭 패널)에 대한 스타일입니다.
    • scrollbar-gutter: stable !important;: 스크롤바 여백을 안정적으로 유지하고, background-color를 연한 회색으로 오버라이드합니다.
    • 이어서 이 특정 tabpanel 내의 WebKit 스크롤바를 커스터마이징하는 규칙이 .chrome-scrollbar와 유사하게 적용됩니다.

12. 기타 스타일

  • .cm-content:focus: cm-content 클래스를 가진 요소에 포커스가 있을 때 기본 외곽선을 제거합니다(outline: none !important;). (아마도 CodeMirror와 같은 코드 편집기 관련 클래스일 수 있습니다.)
  • p.whitespace-pre-wrap a, li a:
    • p 태그 내의 whitespace-pre-wrap 클래스를 가진 링크와 li 태그 내의 링크에 파란색 글자색, 밑줄, 굵은 글씨를 적용합니다.
  • .dark p.whitespace-pre-wrap a, .dark li a:
    • 부모 요소에 .dark 클래스가 있을 경우 (다크 모드일 때), 위의 링크 색상을 더 밝은 파란색(52a0ff)으로 변경합니다.

결론

mobile.css 파일은 다음과 같은 주요 목적을 가집니다:

  1. 반응형 UI: @media 쿼리를 사용하여 화면 크기(특히 모바일)에 따라 내비게이션 바, 버튼, 스크롤바 등의 레이아웃과 가시성을 조정합니다.
  2. 모바일 최적화: 모바일 환경에서 사이드바(nav, sidenav)가 올바르게 작동하고 마스크(nav-mask, sidenav-mask)를 통해 사용자 상호작용을 제어합니다.
  3. UI/UX 개선: 스크롤바를 커스터마이징하거나 숨겨서 디자인 일관성을 유지하고, 애니메이션을 통해 시각적 피드백과 부드러운 전환 효과를 제공합니다.
  4. 특정 라이브러리 지원: Radix UI 컴포넌트의 애니메이션 및 스타일을 명시적으로 정의하여 해당 라이브러리의 UI가 프로젝트 디자인과 잘 통합되도록 합니다.

전반적으로, 이 CSS 파일은 AiChat 애플리케이션이 다양한 화면 크기에서 매끄럽게 작동하고, 사용자에게 일관되고 시각적으로 매력적인 경험을 제공하도록 돕는 역할을 합니다.


style.css

아래는 style.css 내용이다.

@tailwind base;
@tailwind components;
@tailwind utilities;

/* Custom Variables */
:root {
  --white: #fff;
  --black: #000;
  --gray-20: #ececf1;
  --gray-50: #f7f7f8;
  --gray-100: #ececec;
  --gray-200: #e3e3e3;
  --gray-300: #cdcdcd;
  --gray-400: #999696;
  --gray-500: #595959;
  --gray-600: #424242;
  --gray-700: #2f2f2f;
  --gray-800: #212121;
  --gray-850: #171717;
  --gray-900: #0d0d0d;
  --green-50: #ecfdf5;
  --green-100: #d1fae5;
  --green-200: #a7f3d0;
  --green-300: #6ee7b7;
  --green-400: #34d399;
  --green-500: #10b981;
  --green-600: #059669;
  --green-700: #047857;
  --green-800: #065f46;
  --green-900: #064e3b;
  --green-950: #022c22;
  --red-50: #fef2f2;
  --red-100: #fee2e2;
  --red-200: #fecaca;
  --red-300: #fca5a5;
  --red-400: #f87171;
  --red-500: #ef4444;
  --red-600: #dc2626;
  --red-700: #b91c1c;
  --red-800: #991b1b;
  --red-900: #7f1d1d;
  --red-950: #450a0a;
  --amber-50: #fffbeb;
  --amber-100: #fef3c7;
  --amber-200: #fde68a;
  --amber-300: #fcd34d;
  --amber-400: #fbbf24;
  --amber-500: #f59e0b;
  --amber-600: #d97706;
  --amber-700: #b45309;
  --amber-800: #92400e;
  --amber-900: #78350f;
  --amber-950: #451a03;
  --gizmo-gray-500: #999;
  --gizmo-gray-600: #666;
  --gizmo-gray-950: #0f0f0f;
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;
}
html {
  --presentation: var(--white);
  --text-primary: var(--gray-800);
  --text-secondary: var(--gray-600);
  --text-secondary-alt: var(--gray-500);
  --text-tertiary: var(--gray-500);
  --text-warning: var(--amber-500);
  --ring-primary: var(--gray-500);
  --header-primary: var(--white);
  --header-hover: var(--gray-50);
  --header-button-hover: var(--gray-50);
  --surface-active: var(--gray-100);
  --surface-active-alt: var(--gray-200);
  --surface-hover: var(--gray-200);
  --surface-hover-alt: var(--gray-300);
  --surface-primary: var(--white);
  --surface-primary-alt: var(--gray-50);
  --surface-primary-contrast: var(--gray-100);
  --surface-secondary: var(--gray-50);
  --surface-secondary-alt: var(--gray-200);
  --surface-tertiary: var(--gray-100);
  --surface-tertiary-alt: var(--white);
  --surface-dialog: var(--white);
  --surface-submit: var(--green-700);
  --surface-submit-hover: var(--green-800);
  --surface-destructive: var(--red-700);
  --surface-destructive-hover: var(--red-800);
  --surface-chat: var(--white);
  --border-light: var(--gray-200);
  --border-medium-alt: var(--gray-300);
  --border-medium: var(--gray-300);
  --border-heavy: var(--gray-400);
  --border-xheavy: var(--gray-500);
  /* These are test styles */

  --background: 0 0% 100%;
  --foreground: 0 0% 3.9%;
  --card: 0 0% 100%;
  --card-foreground: 0 0% 3.9%;
  --primary: 0 0% 9%;
  --primary-foreground: 0 0% 98%;
  --secondary: 0 0% 96.1%;
  --secondary-foreground: 0 0% 9%;
  --muted: 0 0% 96.1%;
  --muted-foreground: 0 0% 45.1%;
  --accent: 0 0% 96.1%;
  --accent-foreground: 0 0% 9%;
  --destructive: 0 84.2% 60.2%;
  --destructive-foreground: 0 0% 98%;
  --border: 0 0% 89.8%;
  --input: 0 0% 89.8%;
  --ring: 0 0% 3.9%;
  --radius: 0.5rem;
  --chart-1: 12 76% 61%;
  --chart-2: 173 58% 39%;
  --chart-3: 197 37% 24%;
  --chart-4: 43 74% 66%;
  --chart-5: 27 87% 67%;
  --switch-unchecked: 0 0% 58%;
}
.dark {
  --presentation: var(--gray-800);
  --text-primary: var(--gray-100);
  --text-secondary: var(--gray-300);
  --text-secondary-alt: var(--gray-400);
  --text-tertiary: var(--gray-500);
  --text-warning: var(--amber-500);
  --header-primary: var(--gray-700);
  --header-hover: var(--gray-600);
  --header-button-hover: var(--gray-700);
  --surface-active: var(--gray-500);
  --surface-active-alt: var(--gray-700);
  --surface-hover: var(--gray-600);
  --surface-hover-alt: var(--gray-600);
  --surface-primary: var(--gray-900);
  --surface-primary-alt: var(--gray-850);
  --surface-primary-contrast: var(--gray-850);
  --surface-secondary: var(--gray-800);
  --surface-secondary-alt: var(--gray-800);
  --surface-tertiary: var(--gray-700);
  --surface-tertiary-alt: var(--gray-700);
  --surface-dialog: var(--gray-850);
  --surface-submit: var(--green-700);
  --surface-submit-hover: var(--green-800);
  --surface-destructive: var(--red-800);
  --surface-destructive-hover: var(--red-900);
  --surface-chat: var(--gray-700);
  --border-light: var(--gray-700);
  --border-medium-alt: var(--gray-600);
  --border-medium: var(--gray-600);
  --border-heavy: var(--gray-500);
  --border-xheavy: var(--gray-400);
  /* These are test styles */

  --background: 0 0% 7%;
  --foreground: 0 0% 98%;
  --card: 0 0% 3.9%;
  --card-foreground: 0 0% 98%;
  --primary: 0 0% 98%;
  --primary-foreground: 0 0% 9%;
  --secondary: 0 0% 14.9%;
  --secondary-foreground: 0 0% 98%;
  --muted: 0 0% 14.9%;
  --muted-foreground: 0 0% 63.9%;
  --accent: 0 0% 14.9%;
  --accent-foreground: 0 0% 98%;
  --destructive: 0 62.8% 40.6%;
  --destructive-foreground: 0 0% 98%;
  --border: 0 0% 14.9%;
  --input: 0 0% 14.9%;
  --ring: 0 0% 83.1%;
  --chart-1: 220 70% 50%;
  --chart-2: 160 60% 45%;
  --chart-3: 30 80% 55%;
  --chart-4: 280 65% 60%;
  --chart-5: 340 75% 55%;
  --switch-unchecked: 0 0% 40%;
}
.gizmo {
  --text-primary: var(--gizmo-gray-950);
  --text-secondary: var(--gizmo-gray-600);
  --text-tertiary: var(--gizmo-gray-500);
  --surface-primary: var(--white);
  --surface-secondary: var(--gray-50);
  --surface-tertiary: var(--gray-100);
  --border-light: rgba(0, 0, 0, 0.1);
  --border-medium: rgba(0, 0, 0, 0.15);
  --border-heavy: rgba(0, 0, 0, 0.2);
  --border-xheavy: rgba(0, 0, 0, 0.25);
}
.gizmo.dark {
  --text-primary: var(--gray-100);
  --text-secondary: var(--gray-300);
  --text-tertiary: var(--gizmo-gray-500);
  --surface-primary: var(--gray-900);
  --surface-secondary: var(--gray-800);
  --surface-tertiary: var(--gray-700);
  --border-light: rgba(217, 217, 227, 0.1);
  --border-medium: rgba(217, 217, 227, 0.15);
  --border-heavy: rgba(217, 217, 227, 0.2);
  --border-xheavy: rgba(217, 217, 227, 0.25);
}

.text-token-text-primary {
  color: #171717;
  color: var(--text-primary);
}
.text-token-text-secondary {
  color: #565869;
  color: var(--text-secondary);
}
.text-token-text-tertiary {
  color: #8e8ea0;
  color: var(--text-tertiary);
}

.icon-xs {
  stroke-width: 1.5;
  height: 0.75rem;
  width: 0.75rem;
}
.icon-sm {
  stroke-width: 2;
  height: 1rem;
  width: 1rem;
}
.icon-md,
.icon-md-heavy {
  stroke-width: 1.5;
  height: 1.125rem;
  width: 1.125rem;
}
.icon-md-heavy {
  stroke-width: 2.5;
}
.icon-lg {
  stroke-width: 1.5;
  height: 1.5rem;
  width: 1.5rem;
}
.icon-xl {
  stroke-width: 1.5;
  height: 1.75rem;
  width: 1.75rem;
}
.icon-2xl {
  stroke-width: 1.5;
  height: 2rem;
  width: 2rem;
}
.icon-cover {
  stroke-width: 1.5;
  height: 234px;
  width: 234px;
}

.border-token-border-heavy {
  border-color: #c5c5d2;
  border-color: var(--border-heavy);
}

.border-token-border-light {
  border-color: #ececf1;
  border-color: var(--border-light);
}

.border-token-border-medium {
  border-color: #d9d9e3;
  border-color: var(--border-medium);
}

.border-token-surface-primary {
  border-color: #fff;
  border-color: var(--surface-primary);
}

.border-token-surface-secondary {
  border-color: var(--surface-secondary);
}

.border-token-surface-tertiary {
  border-color: #ececf1;
  border-color: var(--surface-tertiary);
}

.bg-token-surface-secondary {
  background-color: var(--surface-secondary);
}

@media (max-width: 640px) {
  .no-gradient-sm {
    background: none !important;
  }
}

.ellipsis {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

@font-face {
  font-display: swap;
  font-family: Inter;
  font-style: normal;
  font-weight: 400;
  src: url('$fonts/Inter-Regular.woff2') format('woff2');
  size-adjust: 94%;
}

@font-face {
  font-display: swap;
  font-family: Inter;
  font-style: italic;
  font-weight: 400;
  src: url('$fonts/Inter-Italic.woff2') format('woff2');
  size-adjust: 94%;
}

@font-face {
  font-display: swap;
  font-family: Inter;
  font-style: normal;
  font-weight: 500;
  src: url('$fonts/Inter-SemiBold.woff2') format('woff2');
  size-adjust: 94%;
}

@font-face {
  font-display: swap;
  font-family: Inter;
  font-style: italic;
  font-weight: 500;
  src: url('$fonts/Inter-SemiBoldItalic.woff2') format('woff2');
  size-adjust: 94%;
}

@font-face {
  font-display: swap;
  font-family: Inter;
  font-style: normal;
  font-weight: 600;
  src: url('$fonts/Inter-Bold.woff2') format('woff2');
  size-adjust: 94%;
}

@font-face {
  font-display: swap;
  font-family: Inter;
  font-style: italic;
  font-weight: 600;
  src: url('$fonts/Inter-BoldItalic.woff2') format('woff2');
  size-adjust: 94%;
}

@font-face {
  font-display: swap;
  font-family: Roboto Mono;
  font-style: normal;
  font-weight: 400;
  src: url('$fonts/roboto-mono-latin-400-normal.woff2') format('woff2');
}

@font-face {
  font-display: swap;
  font-family: Roboto Mono;
  font-style: normal;
  font-weight: 700;
  src: url('$fonts/roboto-mono-latin-700-normal.woff2') format('woff2');
}

@font-face {
  font-display: swap;
  font-family: Roboto Mono;
  font-style: italic;
  font-weight: 400;
  src: url('$fonts/roboto-mono-latin-400-italic.woff2') format('woff2');
}

/*

The default ChatGPT fonts, according to OpenAI's brand guidelines, are proprietary and require appropriate font license according to your use case.

They can be purchased here: https://klim.co.nz/buy/soehne/

The fonts in question are (9 total):

> - Söhne (Buch Kursiv, Buch, Halbfett Kursiv, Halbfett, Kraftig Kursiv, Kraftig, Mono Buch Kursiv, Mono Buch, Mono Halbfett)

If you have purchased a license, you can use the commented-out `@font-face` declarations below to include them in your project.

Step 1: Buy whatever license applies to you and allows use of `.woff2` font files (likely web font license).
Step 2: Place them in ./client/public/fonts/ directory.
Step 3: Replace the current `fontFamily` config in ./client/tailwind.config.cjs with the following:

```
    fontFamily: {
      sans: ['Söhne', 'sans-serif'],
      mono: ['Söhne Mono', 'monospace'],
    },
```

Step 4: Uncomment all Söhne font-face declarations below.
Step 5: rebuild frontend code: `npm run frontend` (or rebuild docker).

*/

/* @font-face {
  font-display: swap;
  font-family: Söhne;
  font-style: normal;
  font-weight: 400;
  src: url("$fonts/soehne-buch.woff2") format("woff2")
}

@font-face {
  font-display: swap;
  font-family: Söhne;
  font-style: italic;
  font-weight: 400;
  src: url("$fonts/soehne-buch-kursiv.woff2") format("woff2")
}

@font-face {
  font-display: swap;
  font-family: Söhne;
  font-style: normal;
  font-weight: 500;
  src: url("$fonts/soehne-kraftig.woff2") format("woff2")
}

@font-face {
  font-display: swap;
  font-family: Söhne;
  font-style: italic;
  font-weight: 500;
  src: url("$fonts/soehne-kraftig-kursiv.woff2") format("woff2")
}

@font-face {
  font-display: swap;
  font-family: Söhne;
  font-style: normal;
  font-weight: 600;
  src: url("$fonts/soehne-halbfett.woff2") format("woff2")
}

@font-face {
  font-display: swap;
  font-family: Söhne;
  font-style: italic;
  font-weight: 600;
  src: url("$fonts/soehne-halbfett-kursiv.woff2") format("woff2")
}

@font-face {
  font-display: swap;
  font-family: Söhne Mono;
  font-style: normal;
  font-weight: 400;
  src: url("$fonts/soehne-mono-buch.woff2") format("woff2")
}

@font-face {
  font-display: swap;
  font-family: Söhne Mono;
  font-style: normal;
  font-weight: 700;
  src: url("$fonts/soehne-mono-halbfett.woff2") format("woff2")
}

@font-face {
  font-display: swap;
  font-family: Söhne Mono;
  font-style: italic;
  font-weight: 400;
  src: url("$fonts/soehne-mono-buch-kursiv.woff2") format("woff2")
} */

/* * {
  box-sizing: border-box;
  outline: 1px solid limegreen !important;
} */

/* p small {
  opacity: 0;
  animation: fadeIn 3s ease forwards;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
} */

/* .LazyLoad {
  opacity: 0;
  transition: all 1s ease-in-out;
} */

select {
  --tw-shadow: 0 0 transparent;
  -webkit-appearance: none;
  appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%238e8ea0' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");
  background-position: right 0.5rem center;
  background-repeat: no-repeat;
  background-size: 1.5em 1.5em;
  padding-right: 2.5rem;
  background-color: #fff;
  border-color: #8e8ea0;
  border-radius: 0;
  border-width: 1px;
  font-size: 1rem;
  line-height: 1.5rem;
}

.overflow-y-auto {
  overflow-y: overlay;
}

.overflow-x-auto {
  overflow-x: overlay;
}

.reset-rc-number-input input {
  width: 100%;
  border: none !important;
  background: transparent;
}

.reset-rc-number-input-text-right input {
  text-align: right;
}

.option-buttons {
  pointer-events: none;
  opacity: 0;
  transition: all 0.25s ease-in-out;
}

.option-buttons.full-opacity {
  pointer-events: fill;
  opacity: 1;
}

.option-buttons.show {
  pointer-events: fill;
  opacity: 1;
}

.options-bar {
  pointer-events: none;
  opacity: 0;
  transition: all 0.25s ease-in-out;
}

.options-bar.full-opacity {
  pointer-events: fill;
  opacity: 1;
}

.options-bar.show {
  pointer-events: fill;
  opacity: 0.3;
}

.hidden {
  display: none;
}

.creative-tab {
  /* background: linear-gradient(90deg, #904887 10.79%, #8B257E 87.08%); */
  background: linear-gradient(90deg, #904887 10.79%, #8b257e 87.08%);
}

.fast-tab {
  background: linear-gradient(90deg, #2870ea 10.79%, #1b4aef 87.08%);
}

.balanced-tab {
  background: linear-gradient(90deg, #d7871a 10.79%, #9f6005 87.08%);
}

.precise-tab {
  background: linear-gradient(90deg, #006880 10.79%, #005366 87.08%);
}

p > small {
  opacity: 0;
  animation: fadein 3s forwards;
}

.fade-in {
  animation: fadeInWithOutTranslate 0.3s ease-in-out;
}

@keyframes fadeInWithOutTranslate {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadein {
  from {
    opacity: 0;
    transform: translateY(-20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

blockquote,
dd,
dl,
fieldset,
figure,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
p,
pre {
  margin: 0;
}

.scroll-animation-enter {
  opacity: 0;
  transform: translateY(20px) scale(0.7) rotate(-5deg);
  pointer-events: none;
}

.scroll-animation-enter-done {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.scroll-animation-exit-done {
  display: none;
}

@keyframes twist-entrance {
  0% {
    transform: translateY(20px) scale(0.7) rotate(-5deg);
    opacity: 0;
  }
  60% {
    transform: translateY(2px) scale(0.95) rotate(2deg);
    opacity: 0.9;
  }
  100% {
    transform: translateY(0) scale(1) rotate(0deg);
    opacity: 1;
  }
}

.scroll-animation-enter-active {
  animation: twist-entrance 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
  transition-delay: 50ms;
}

@keyframes twist-exit {
  0% {
    transform: translateY(0) scale(1) rotate(0deg);
    opacity: 1;
  }
  40% {
    transform: translateY(5px) scale(0.95) rotate(2deg);
    opacity: 0.7;
  }
  100% {
    transform: translateY(20px) scale(0.7) rotate(-5deg);
    opacity: 0;
  }
}

.scroll-animation-exit-active {
  animation: twist-exit 0.4s cubic-bezier(0.55, 0.085, 0.68, 0.53) forwards;
  pointer-events: none;
}

.premium-scroll-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border-radius: 50%;
  box-shadow:
    0 2px 8px rgba(0, 0, 0, 0.05),
    0 4px 12px rgba(0, 0, 0, 0.08),
    0 0 0 1px rgba(255, 255, 255, 0.08);
  background-color: rgba(255, 255, 255, 0.9);
  z-index: 10;
  transition:
    transform 500ms cubic-bezier(0.25, 0.1, 0.25, 1),
    box-shadow 500ms cubic-bezier(0.25, 0.1, 0.25, 1);
  overflow: hidden;
}

.dark .premium-scroll-button {
  box-shadow:
    0 2px 8px rgba(0, 0, 0, 0.2),
    0 4px 12px rgba(0, 0, 0, 0.25),
    0 0 0 1px rgba(255, 255, 255, 0.06);
  background-color: rgba(35, 35, 40, 0.9);
}

.scroll-animation-enter-active .premium-scroll-button {
  pointer-events: none !important;
}

.premium-scroll-button:hover:not(:active) {
  transform: translateY(-1.5px) scale(1.02);
  box-shadow:
    0 5px 10px rgba(0, 0, 0, 0.07),
    0 7px 14px rgba(0, 0, 0, 0.1),
    0 0 0 1px rgba(255, 255, 255, 0.1);
}

.premium-scroll-button:active {
  transform: translateY(1px) scale(0.98);
  transition: all 150ms cubic-bezier(0.2, 0, 0.2, 1);
  box-shadow:
    0 1px 4px rgba(0, 0, 0, 0.1),
    0 2px 8px rgba(0, 0, 0, 0.08),
    0 0 0 1px rgba(255, 255, 255, 0.08);
}

@keyframes float {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-1px);
  }
}

.scroll-animation-enter-done .premium-scroll-button {
  animation: float 2s ease-in-out infinite;
}

.premium-scroll-button:hover,
.premium-scroll-button:active {
  animation: none;
}

.blink {
  animation: blink 1s linear infinite;
}
@keyframes blink {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

.cursorBlink {
  animation: blink 1s linear infinite;
}
@keyframes blink {
  0% {
    opacity: 1;
  }
  79% {
    opacity: 1;
  }
  80% {
    opacity: 0;
  }
  99% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

.blink2 {
  animation: blink 1500ms linear infinite;
}
@keyframes blink2 {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

.prose {
  color: var(--tw-prose-body);
  max-width: 65ch;
  font-size: var(--markdown-font-size, var(--font-size-base));
  line-height: calc(
    28px * var(--markdown-font-size, var(--font-size-base)) / var(--font-size-base)
  );
}

.prose :where([class~='lead']):not(:where([class~='not-prose'] *)) {
  color: var(--tw-prose-lead);
  font-size: 1.25em;
  line-height: 1.6;
  margin-bottom: 1.2em;
  margin-top: 1.2em;
}
.prose :where(a):not(:where([class~='not-prose'] *)) {
  color: var(--tw-prose-links);
  font-weight: 500;
  text-decoration: underline;
}
.prose :where(strong):not(:where([class~='not-prose'] *)) {
  color: var(--tw-prose-bold);
  font-weight: 600;
}
.prose :where(a strong):not(:where([class~='not-prose'] *)) {
  color: inherit;
}
.prose :where(blockquote strong):not(:where([class~='not-prose'] *)) {
  color: inherit;
}
.prose :where(thead th strong):not(:where([class~='not-prose'] *)) {
  color: inherit;
}
.prose :where(ul > li):not(:where([class~='not-prose'] *))::marker {
  color: var(--tw-prose-bullets);
}
.prose :where(hr):not(:where([class~='not-prose'] *)) {
  border-color: var(--tw-prose-hr);
  border-top-width: 1px;
  margin-bottom: 3em;
  margin-top: 3em;
}
.prose :where(blockquote):not(:where([class~='not-prose'] *)) {
  border-left-color: var(--tw-prose-quote-borders);
  border-left-width: 0.25rem;
  color: var(--tw-prose-quotes);
  font-style: italic;
  font-style: normal;
  font-weight: 500;
  margin-bottom: 1.6em;
  margin-top: 1.6em;
  padding-left: 1em;
  quotes: '\201C' '\201D' '\2018' '\2019';
}
.prose :where(blockquote p:first-of-type):not(:where([class~='not-prose'] *)):before {
  content: open-quote;
}
.prose :where(blockquote p:last-of-type):not(:where([class~='not-prose'] *)):after {
  content: close-quote;
}
.prose :where(h1):not(:where([class~='not-prose'] *)) {
  color: var(--tw-prose-headings);
  font-size: 2.25em;
  font-weight: 800;
  line-height: 1.1111111;
  margin-bottom: 0.8888889em;
  margin-top: 0;
}
.prose :where(h1 strong):not(:where([class~='not-prose'] *)) {
  color: inherit;
  font-weight: 900;
}
.prose :where(h2):not(:where([class~='not-prose'] *)) {
  color: var(--tw-prose-headings);
  font-size: 1.5em;
  font-weight: 700;
  line-height: 1.3333333;
  margin-bottom: 1em;
  margin-top: 2em;
}
.prose :where(h2 strong):not(:where([class~='not-prose'] *)) {
  color: inherit;
  font-weight: 800;
}
.prose :where(h3):not(:where([class~='not-prose'] *)) {
  color: var(--tw-prose-headings);
  font-size: 1.25em;
  font-weight: 600;
  line-height: 1.6;
  margin-bottom: 0.6em;
  margin-top: 1.6em;
}
.prose :where(h3 strong):not(:where([class~='not-prose'] *)) {
  color: inherit;
  font-weight: 700;
}
.prose :where(h4):not(:where([class~='not-prose'] *)) {
  color: var(--tw-prose-headings);
  font-weight: 600;
  line-height: 1.5;
  margin-bottom: 0.5em;
  margin-top: 1.5em;
}
.prose :where(h4 strong):not(:where([class~='not-prose'] *)) {
  color: inherit;
  font-weight: 700;
}
.prose :where(img):not(:where([class~='not-prose'] *)) {
  margin-bottom: 2em;
  margin-top: 2em;
}
.prose :where(figure > *):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0;
  margin-top: 0;
}
.prose :where(figcaption):not(:where([class~='not-prose'] *)) {
  color: var(--tw-prose-captions);
  font-size: 0.875em;
  line-height: 1.4285714;
  margin-top: 0.8571429em;
}
.prose :where(code):not(:where([class~='not-prose'] *)) {
  color: var(--tw-prose-code);
  font-size: 0.875em;
  font-weight: 600;
}
.prose :where(code):not(:where([class~='not-prose'] *)):before {
  content: '`';
}
.prose :where(code):not(:where([class~='not-prose'] *)):after {
  content: '`';
}
.prose :where(a code):not(:where([class~='not-prose'] *)) {
  color: inherit;
}
.prose :where(h1 code):not(:where([class~='not-prose'] *)) {
  color: inherit;
}
.prose :where(h2 code):not(:where([class~='not-prose'] *)) {
  color: inherit;
  font-size: 0.875em;
}
.prose :where(h3 code):not(:where([class~='not-prose'] *)) {
  color: inherit;
  font-size: 0.9em;
}
.prose :where(h4 code):not(:where([class~='not-prose'] *)) {
  color: inherit;
}
.prose :where(blockquote code):not(:where([class~='not-prose'] *)) {
  color: inherit;
}
.prose :where(thead th code):not(:where([class~='not-prose'] *)) {
  color: inherit;
}
.prose :where(pre):not(:where([class~='not-prose'] *)) {
  background-color: transparent;
  border-radius: 0.375rem;
  color: currentColor;
  font-size: 0.875em;
  font-weight: 400;
  line-height: 1.7142857;
  margin: 0;
  overflow-x: auto;
  padding: 0;
}
.prose :where(pre code):not(:where([class~='not-prose'] *)) {
  background-color: transparent;
  border-radius: 0;
  border-width: 0;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  padding: 0;
}
.prose :where(pre code):not(:where([class~='not-prose'] *)):before {
  content: none;
}
.prose :where(pre code):not(:where([class~='not-prose'] *)):after {
  content: none;
}
.prose :where(table):not(:where([class~='not-prose'] *)) {
  font-size: 0.875em;
  line-height: 1.7142857;
  margin-bottom: 2em;
  margin-top: 2em;
  table-layout: auto;
  text-align: left;
  width: 100%;
}
.prose :where(thead):not(:where([class~='not-prose'] *)) {
  border-bottom-color: var(--tw-prose-th-borders);
  border-bottom-width: 1px;
}
.prose :where(thead th):not(:where([class~='not-prose'] *)) {
  color: var(--tw-prose-headings);
  font-weight: 600;
  padding-bottom: 0.5714286em;
  padding-left: 0.5714286em;
  padding-right: 0.5714286em;
  vertical-align: bottom;
}
.prose :where(tbody tr):not(:where([class~='not-prose'] *)) {
  border-bottom-color: var(--tw-prose-td-borders);
  border-bottom-width: 1px;
}
.prose :where(tbody tr:last-child):not(:where([class~='not-prose'] *)) {
  border-bottom-width: 0;
}
.prose :where(tbody td):not(:where([class~='not-prose'] *)) {
  vertical-align: baseline;
}
.prose :where(tfoot):not(:where([class~='not-prose'] *)) {
  border-top-color: var(--tw-prose-th-borders);
  border-top-width: 1px;
}
.prose :where(tfoot td):not(:where([class~='not-prose'] *)) {
  vertical-align: top;
}
.prose {
  --tw-prose-body: #374151;
  --tw-prose-headings: #111827;
  --tw-prose-lead: #4b5563;
  --tw-prose-links: #0066cc;
  --tw-prose-bold: #111827;
  --tw-prose-counters: #6b7280;
  --tw-prose-bullets: #d1d5db;
  --tw-prose-hr: #e5e7eb;
  --tw-prose-quotes: #111827;
  --tw-prose-quote-borders: #e5e7eb;
  --tw-prose-captions: #6b7280;
  --tw-prose-code: #111827;
  --tw-prose-pre-code: #e5e7eb;
  --tw-prose-pre-bg: #1f2937;
  --tw-prose-th-borders: #d1d5db;
  --tw-prose-td-borders: #e5e7eb;
  --tw-prose-invert-body: #d1d5db;
  --tw-prose-invert-headings: #fff;
  --tw-prose-invert-lead: #9ca3af;
  --tw-prose-invert-links: #fff;
  --tw-prose-invert-bold: #fff;
  --tw-prose-invert-counters: #9ca3af;
  --tw-prose-invert-bullets: #4b5563;
  --tw-prose-invert-hr: #374151;
  --tw-prose-invert-quotes: #f3f4f6;
  --tw-prose-invert-quote-borders: #374151;
  --tw-prose-invert-captions: #9ca3af;
  --tw-prose-invert-code: #fff;
  --tw-prose-invert-pre-code: #d1d5db;
  --tw-prose-invert-pre-bg: rgba(0, 0, 0, 0.5);
  --tw-prose-invert-th-borders: #4b5563;
  --tw-prose-invert-td-borders: #374151;
  font-size: 1rem;
  line-height: 1.75;
}
.prose :where(p):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.25em;
  margin-top: 1.25em;
}
.prose :where(video):not(:where([class~='not-prose'] *)) {
  margin-bottom: 2em;
  margin-top: 2em;
}
.prose :where(figure):not(:where([class~='not-prose'] *)) {
  margin-bottom: 2em;
  margin-top: 2em;
}
.prose :where(li):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0.5em;
  margin-top: 0.5em;
}
.prose :where(ul > li):not(:where([class~='not-prose'] *)) {
  padding-left: 0.375em;
}
.prose :where(.prose > ul > li p):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0.75em;
  margin-top: 0.75em;
}
.prose :where(.prose > ul > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose :where(.prose > ul > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.25em;
}
.prose :where(hr + *):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose :where(h2 + *):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose :where(h3 + *):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose :where(h4 + *):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose :where(thead th:first-child):not(:where([class~='not-prose'] *)) {
  padding-left: 0;
}
.prose :where(thead th:last-child):not(:where([class~='not-prose'] *)) {
  padding-right: 0;
}
.prose :where(tbody td, tfoot td):not(:where([class~='not-prose'] *)) {
  padding: 0.5714286em;
}
.prose :where(tbody td:first-child, tfoot td:first-child):not(:where([class~='not-prose'] *)) {
  padding-left: 0;
}
.prose :where(tbody td:last-child, tfoot td:last-child):not(:where([class~='not-prose'] *)) {
  padding-right: 0;
}
.prose :where(.prose > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose :where(.prose > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0;
}
.prose-sm :where(.prose > ul > li p):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0.5714286em;
  margin-top: 0.5714286em;
}
.prose-sm :where(.prose > ul > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 1.1428571em;
}
.prose-sm :where(.prose > ul > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.1428571em;
}
.prose-sm :where(.prose > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose-sm :where(.prose > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0;
}
.prose-base :where(.prose > ul > li p):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0.75em;
  margin-top: 0.75em;
}
.prose-base :where(.prose > ul > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose-base :where(.prose > ul > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.25em;
}
.prose-base :where(.prose > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose-base :where(.prose > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0;
}
.prose-lg :where(.prose > ul > li p):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0.8888889em;
  margin-top: 0.8888889em;
}
.prose-lg :where(.prose > ul > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 1.3333333em;
}
.prose-lg :where(.prose > ul > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.3333333em;
}
.prose-lg :where(.prose > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose-lg :where(.prose > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0;
}
.prose-xl :where(.prose > ul > li p):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0.8em;
  margin-top: 0.8em;
}
.prose-xl :where(.prose > ul > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 1.2em;
}
.prose-xl :where(.prose > ul > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.2em;
}
.prose-xl :where(.prose > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose-xl :where(.prose > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0;
}
.prose-2xl :where(.prose > ul > li p):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0.8333333em;
  margin-top: 0.8333333em;
}
.prose-2xl :where(.prose > ul > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 1.3333333em;
}
.prose-2xl :where(.prose > ul > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.3333333em;
}
.prose-2xl :where(.prose > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose-2xl :where(.prose > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0;
}

code,
pre {
  font-family:
    Consolas,
    Söhne Mono,
    Monaco,
    Andale Mono,
    Ubuntu Mono,
    monospace !important;
}
code[class='language-plaintext'] {
  white-space: pre-line;
}
code.hljs,
code[class*='language-'],
pre[class*='language-'] {
  word-wrap: normal;
  background: none;
  color: #fff;
  -webkit-hyphens: none;
  hyphens: none;
  font-size: 0.85rem;
  line-height: 1.5;
  tab-size: 4;
  text-align: left;
  white-space: pre;
  word-break: normal;
  word-spacing: normal;
}
pre[class*='language-'] {
  border-radius: 0.3em;
  overflow: auto;
}
:not(pre) > code.hljs,
:not(pre) > code[class*='language-'] {
  border-radius: 0.3em;
  padding: 0.1em;
  white-space: normal;
}
.hljs-comment {
  color: hsla(0, 0%, 100%, 0.5);
}
.hljs-meta {
  color: hsla(0, 0%, 100%, 0.6);
}
.hljs-built_in,
.hljs-class .hljs-title {
  color: #e9950c;
}
.hljs-doctag,
.hljs-formula,
.hljs-keyword,
.hljs-literal {
  color: #2e95d3;
}
.hljs-addition,
.hljs-attribute,
.hljs-meta-string,
.hljs-regexp,
.hljs-string {
  color: #00a67d;
}
.hljs-attr,
.hljs-number,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-selector-pseudo,
.hljs-template-variable,
.hljs-type,
.hljs-variable {
  color: #df3079;
}
.hljs-bullet,
.hljs-link,
.hljs-selector-id,
.hljs-symbol,
.hljs-title {
  color: #f22c3d;
}

[role='button'],
button {
  cursor: pointer;
}

.btn {
  align-items: center;
  border-color: transparent;
  border-radius: 0.5rem;
  border-width: 1px;
  cursor: pointer;
  display: inline-flex;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.25rem;
  padding: 0.5rem 0.75rem;
  pointer-events: auto;
  transition: all 0.1s ease-in-out;
}
.custom-btn {
  align-items: center;
  border-color: transparent;
  border-radius: 0.25rem;
  border-width: 1px;
  display: inline-flex;
  font-size: 0.875rem;
  line-height: 1.25rem;
  padding: 0.5rem 0.75rem;
  transition: all 0.1s ease-in-out;
}
.btn:focus {
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.btn:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}
.btn-primary {
  --tw-bg-opacity: 1;
  --tw-text-opacity: 1;
  background-color: rgba(16, 163, 127, var(--tw-bg-opacity));
  color: rgba(255, 255, 255, var(--tw-text-opacity));
}
.btn-primary:hover {
  --tw-bg-opacity: 1;
  background-color: rgba(26, 127, 100, var(--tw-bg-opacity));
}
.btn-primary:focus {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
    var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width))
    var(--tw-ring-color);
  --tw-ring-offset-width: 2px;
  box-shadow:
    var(--tw-ring-offset-shadow),
    var(--tw-ring-shadow),
    0 0 transparent;
  box-shadow:
    var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 transparent);
}
.btn-primary.focus-visible {
  --tw-ring-opacity: 1;
  --tw-ring-color: rgba(25, 195, 125, var(--tw-ring-opacity));
}
.btn-primary:focus-visible {
  --tw-ring-opacity: 1;
  --tw-ring-color: rgba(25, 195, 125, var(--tw-ring-opacity));
}
.btn-primary:disabled:hover {
  --tw-bg-opacity: 1;
  background-color: rgba(16, 163, 127, var(--tw-bg-opacity));
}
.btn-secondary {
  --tw-border-opacity: 1;
  --tw-bg-opacity: 1;
  --tw-text-opacity: 1;
  background-color: transparent;
  background-color: rgba(16, 163, 156, var(--tw-bg-opacity));
  color: rgba(255, 255, 255, var(--tw-text-opacity));
}
.btn-secondary:hover {
  --tw-bg-opacity: 1;
  border-color: rgba(0, 0, 0, 0.1);
  color: rgba(64, 65, 79, var(--tw-text-opacity));
  background-color: rgba(236, 236, 241, var(--tw-bg-opacity));
}
.dark .btn-secondary:hover {
  --tw-bg-opacity: 1;
  border-color: rgba(8, 82, 78, var(--tw-border-opacity));
  color: rgba(255, 255, 240, var(--tw-text-opacity));
  background-color: rgba(8, 82, 78, var(--tw-bg-opacity));
}
.btn-neutral {
  --tw-bg-opacity: 1;
  --tw-text-opacity: 1;
  background-color: var(--surface-secondary);
  border-color: rgba(0, 0, 0, 0.1);
  border-width: 1px;
  color: rgba(64, 65, 79, var(--tw-text-opacity));
  font-size: 0.875rem;
  line-height: 1.25rem;
  transition: all 0.1s ease-in-out;
}

.btn-neutral:hover {
  --tw-bg-opacity: 1;
  background-color: rgba(236, 236, 241, var(--tw-bg-opacity));
}

.btn-neutral:focus {
  outline: none;
  box-shadow: 0 0 0 2px var(--ring-primary);
}

.dark .btn-neutral {
  --tw-border-opacity: 1;
  --tw-bg-opacity: 1;
  --tw-text-opacity: 1;
  background-color: transparent;
  border-color: rgba(66, 66, 66, var(--tw-border-opacity));
  color: rgba(255, 255, 240, var(--tw-text-opacity));
}

.dark .btn-neutral:hover {
  --tw-bg-opacity: 1;
  background-color: rgba(66, 66, 66, var(--tw-bg-opacity));
}

.dark .btn-neutral:focus {
  box-shadow: 0 0 0 2px var(--ring-primary);
}
.btn-small {
  padding: 0.25rem 0.5rem;
}

.from-token-surface-secondary {
  --tw-gradient-from: var(--surface-secondary) var(--tw-gradient-from-position);
  --tw-gradient-to: hsla(0, 0%, 100%, 0) var(--tw-gradient-to-position);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}

/* Webkit scrollbar */
::-webkit-scrollbar {
  height: 0.1em;
  width: 0.5rem;
}

::-webkit-scrollbar-thumb {
  background-color: rgba(0, 0, 0, 0.1);
  border-radius: 9999px;
}

.dark ::-webkit-scrollbar-thumb {
  background-color: hsla(0, 0%, 100%, 0.1);
}

::-webkit-scrollbar-track {
  background-color: transparent;
  border-radius: 9999px;
}

.scrollbar-transparent::-webkit-scrollbar-thumb {
  background-color: transparent;
}

.dark .scrollbar-transparent::-webkit-scrollbar-thumb {
  background-color: transparent;
}

body,
html {
  height: 100%;
}

.dark body,
.dark html {
  --tw-bg-opacity: 1;
  background-color: rgba(23, 23, 23, var(--tw-bg-opacity));
}

#__next,
#root {
  height: 100%;
}

.markdown {
  max-width: none;
  font-size: var(--markdown-font-size, var(--font-size-base));
  line-height: calc(
    28px * var(--markdown-font-size, var(--font-size-base)) / var(--font-size-base)
  );
}

.markdown h1 {
  font-size: calc(var(--markdown-font-size) * 1.75);
}
.markdown h2 {
  font-size: calc(var(--markdown-font-size) * 1.5);
}

.markdown h2 {
  margin-bottom: 1rem;
  margin-top: 2rem;
}

.markdown h3 {
  font-weight: 600;
  font-size: calc(var(--markdown-font-size) * 1.25);
}

.markdown h3,
.markdown h4 {
  margin-bottom: 0.5rem;
  margin-top: 1rem;
}

.markdown h4 {
  font-weight: 400;
  font-size: calc(var(--markdown-font-size) * 1.1);
}

.markdown h5 {
  font-weight: 600;
  font-size: var(--markdown-font-size);
}

.markdown blockquote {
  --tw-border-opacity: 1;
  border-color: rgba(142, 142, 160, var(--tw-border-opacity));
  border-left-width: 2px;
  line-height: 1rem;
  padding-left: 1rem;
}

.markdown table {
  --tw-border-spacing-x: 0px;
  --tw-border-spacing-y: 0px;
  border-collapse: separate;
  border-spacing: var(--tw-border-spacing-x) var(--tw-border-spacing-y);
  width: 100%;
}

.markdown th {
  background-color: rgba(236, 236, 241, 0.2);
  border-bottom-width: 1px;
  border-left-width: 1px;
  border-top-width: 1px;
  padding: 0.25rem 0.75rem;
}

.markdown th:first-child {
  border-top-left-radius: 0.375rem;
}

.markdown th:last-child {
  border-right-width: 1px;
  border-top-right-radius: 0.375rem;
}

.markdown td {
  border-bottom-width: 1px;
  border-left-width: 1px;
  padding: 0.25rem 0.75rem;
}

.markdown td:last-child {
  border-right-width: 1px;
}

.markdown tbody tr:last-child td:first-child {
  border-bottom-left-radius: 0.375rem;
}

.markdown tbody tr:last-child td:last-child {
  border-bottom-right-radius: 0.375rem;
}

.markdown a {
  text-decoration-line: underline;
  text-underline-offset: 2px;
}

.animate-flash {
  -webkit-animation: flash 2s steps(60, start);
  animation: flash 2s steps(60, start);
}

@-webkit-keyframes flash {
  0% {
    background-color: hsla(0, 0%, 100%, 0.4);
  }
}

@keyframes flash {
  0% {
    background-color: hsla(0, 0%, 100%, 0.4);
  }
}

.truncate {
  overflow: hidden;
  white-space: nowrap;
}

.text-ellipsis,
.truncate {
  text-overflow: ellipsis;
}

.group:hover .group-hover\:visible {
  visibility: visible;
}
.group:hover .group-hover\:from-\[\#2A2B32\] {
  --tw-gradient-from: #2a2b32;
  --tw-gradient-to: rgba(42, 43, 50, 0);
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
}
.group:hover .group-hover\:text-gray-500 {
  --tw-text-opacity: 1;
  color: rgba(142, 142, 160, var(--tw-text-opacity));
}
.group:hover .group-hover\:text-gray-700 {
  --tw-text-opacity: 1;
  color: rgba(64, 65, 79, var(--tw-text-opacity));
}
.dark .dark\:prose-invert {
  --tw-prose-body: var(--tw-prose-invert-body);
  --tw-prose-headings: var(--tw-prose-invert-headings);
  --tw-prose-lead: var(--tw-prose-invert-lead);
  --tw-prose-links: var(--tw-prose-invert-links);
  --tw-prose-bold: var(--tw-prose-invert-bold);
  --tw-prose-counters: var(--tw-prose-invert-counters);
  --tw-prose-bullets: var(--tw-prose-invert-bullets);
  --tw-prose-hr: var(--tw-prose-invert-hr);
  --tw-prose-quotes: var(--tw-prose-invert-quotes);
  --tw-prose-quote-borders: var(--tw-prose-invert-quote-borders);
  --tw-prose-captions: var(--tw-prose-invert-captions);
  --tw-prose-code: var(--tw-prose-invert-code);
  --tw-prose-pre-code: var(--tw-prose-invert-pre-code);
  --tw-prose-pre-bg: var(--tw-prose-invert-pre-bg);
  --tw-prose-th-borders: var(--tw-prose-invert-th-borders);
  --tw-prose-td-borders: var(--tw-prose-invert-td-borders);
}

@-webkit-keyframes spin {
  to {
    -webkit-transform: rotate(1turn);
    transform: rotate(1turn);
  }
}
@keyframes spin {
  to {
    -webkit-transform: rotate(1turn);
    transform: rotate(1turn);
  }
}
.animate-spin {
  -webkit-animation: spin 1s linear infinite;
  animation: spin 1s linear infinite;
}

.form-input,
.form-multiselect,
.form-select,
.form-textarea {
  --tw-shadow: 0 0 transparent;
  -webkit-appearance: none;
  appearance: none;
  background-color: #fff;
  border-color: #8e8ea0;
  border-radius: 0;
  border-width: 1px;
  font-size: 1rem;
  line-height: 1.5rem;
  padding: 0.5rem 0.75rem;
}
.form-input:focus,
.form-multiselect:focus,
.form-select:focus,
.form-textarea:focus {
  --tw-ring-inset: var(--tw-empty, /*!*/ /*!*/);
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: #2563eb;
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width)
    var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width))
    var(--tw-ring-color);
  border-color: #2563eb;
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.form-input::-webkit-input-placeholder,
.form-textarea::-webkit-input-placeholder {
  color: #8e8ea0;
  opacity: 1;
}
.form-input::placeholder,
.form-textarea::placeholder {
  color: #8e8ea0;
  opacity: 1;
}
.form-input::-webkit-datetime-edit-fields-wrapper {
  padding: 0;
}
.form-input::-webkit-date-and-time-value {
  min-height: 1.5em;
}
.form-input::-webkit-datetime-edit,
.form-input::-webkit-datetime-edit-day-field,
.form-input::-webkit-datetime-edit-hour-field,
.form-input::-webkit-datetime-edit-meridiem-field,
.form-input::-webkit-datetime-edit-millisecond-field,
.form-input::-webkit-datetime-edit-minute-field,
.form-input::-webkit-datetime-edit-month-field,
.form-input::-webkit-datetime-edit-second-field,
.form-input::-webkit-datetime-edit-year-field {
  padding-bottom: 0;
  padding-top: 0;
}

.grow {
  flex-grow: 1;
}

.transform {
  -webkit-transform: translate(var(--tw-translate-x), var(--tw-translate-y))
    rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
    scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate))
    skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x))
    scaleY(var(--tw-scale-y));
}
body,
html {
  height: 100%;
}
.dark body,
.dark html {
  --tw-bg-opacity: 1;
  background-color: rgba(33, 33, 33, var(--tw-bg-opacity));
}
#__next,
#root {
  height: 100%;
}

.markdown {
  max-width: none;
}
.markdown h1,
.markdown h2 {
  font-weight: 600;
}
.markdown h2 {
  margin-bottom: 1rem;
  margin-top: 2rem;
}
.markdown h3 {
  font-weight: 600;
}
.markdown h3,
.markdown h4 {
  margin-bottom: 0.5rem;
  margin-top: 1rem;
}
.markdown h4 {
  font-weight: 400;
}
.markdown h5 {
  font-weight: 600;
}
.markdown blockquote {
  --tw-border-opacity: 1;
  border-color: rgba(142, 142, 160, var(--tw-border-opacity));
  border-left-width: 2px;
  line-height: 1rem;
  padding-left: 1rem;
}
.markdown table {
  --tw-border-spacing-x: 0px;
  --tw-border-spacing-y: 0px;
  border-collapse: separate;
  border-spacing: var(--tw-border-spacing-x) var(--tw-border-spacing-y);
  width: 100%;
}
.markdown th {
  background-color: rgba(236, 236, 241, 0.2);
  border-bottom-width: 1px;
  border-left-width: 1px;
  border-top-width: 1px;
  padding: 0.25rem 0.75rem;
}
.markdown th:first-child {
  border-top-left-radius: 0.375rem;
}
.markdown th:last-child {
  border-right-width: 1px;
  border-top-right-radius: 0.375rem;
}
.markdown td {
  border-bottom-width: 1px;
  border-left-width: 1px;
  padding: 0.25rem 0.75rem;
}
.markdown td:last-child {
  border-right-width: 1px;
}
.markdown tbody tr:last-child td:first-child {
  border-bottom-left-radius: 0.375rem;
}
.markdown tbody tr:last-child td:last-child {
  border-bottom-right-radius: 0.375rem;
}
.markdown a {
  text-decoration-line: underline;
  text-underline-offset: 2px;
}
.conversation-item-time:before {
  content: attr(data-time);
}
.tooltip-label:before {
  content: attr(data-content);
}

@-webkit-keyframes blink {
  to {
    visibility: hidden;
  }
}
@keyframes blink {
  to {
    visibility: hidden;
  }
}
.animate-flash {
  -webkit-animation: flash 2s steps(60, start);
  animation: flash 2s steps(60, start);
}
@-webkit-keyframes flash {
  0% {
    background-color: hsla(0, 0%, 100%, 0.4);
  }
}
@keyframes flash {
  0% {
    background-color: hsla(0, 0%, 100%, 0.4);
  }
}
.hidden-visibility {
  visibility: hidden;
}

.toast-root {
  align-items: center;
  display: flex;
  flex-direction: column;
  height: 0;
  transition: all 0.24s cubic-bezier(0, 0, 0.2, 1);
}

.toast-root[data-state='open'] {
  -webkit-animation: toast-open 0.24s cubic-bezier(0.175, 0.885, 0.32, 1.175) both;
  animation: toast-open 0.24s cubic-bezier(0.175, 0.885, 0.32, 1.175) both;
}
.toast-root[data-state='closed'] {
  -webkit-animation: toast-close 0.12s cubic-bezier(0.4, 0, 1, 1) both;
  animation: toast-close 0.12s cubic-bezier(0.4, 0, 1, 1) both;
}
.toast-root .alert-root {
  box-shadow:
    0 0 1px rgba(67, 90, 111, 0.3),
    0 5px 8px -4px rgba(67, 90, 111, 0.3);
  flex-shrink: 0;
  pointer-events: all;
}

@-webkit-keyframes toast-open {
  0% {
    opacity: 0;
    -webkit-transform: translateY(-100%);
    transform: translateY(-100%);
  }
  to {
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
}
@keyframes toast-open {
  0% {
    opacity: 0;
    -webkit-transform: translateY(-100%);
    transform: translateY(-100%);
  }
  to {
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
}
@-webkit-keyframes toast-close {
  0% {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
@keyframes toast-close {
  0% {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

@-webkit-keyframes pulseSize {
  0%,
  to {
    -webkit-transform: scaleX(1);
    transform: scaleX(1);
  }
  50% {
    -webkit-transform: scale3d(1.25, 1.25, 1);
    transform: scale3d(1.25, 1.25, 1);
  }
}
@keyframes pulseSize {
  0%,
  to {
    -webkit-transform: scaleX(1);
    transform: scaleX(1);
  }
  50% {
    -webkit-transform: scale3d(1.25, 1.25, 1);
    transform: scale3d(1.25, 1.25, 1);
  }
}
.submitting .result-thinking:empty:last-child:after {
  -webkit-font-smoothing: subpixel-antialiased;
  -webkit-animation: pulseSize 1.25s ease-in-out infinite;
  animation: pulseSize 1.25s ease-in-out infinite;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  background-color: #0d0d0d;
  background-color: var(--text-primary);
  border-radius: 50%;
  box-sizing: border-box;
  content: ' ';
  display: block;
  height: 12px;
  position: absolute;
  top: -11px;
  -webkit-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-transform-origin: center;
  transform-origin: center;
  width: 12px;
  will-change: transform;
}

.shadow-stroke {
  position: relative;
}
.shadow-stroke:after {
  --tw-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
  --tw-shadow-colored: inset 0 0 0 1px var(--tw-shadow-color);
  border-radius: 9999px;
  bottom: 0;
  content: '';
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
}
.dark .shadow-stroke:after,
.shadow-stroke:after {
  box-shadow:
    0 0 transparent,
    0 0 transparent,
    var(--tw-shadow);
  box-shadow:
    var(--tw-ring-offset-shadow, 0 0 transparent), var(--tw-ring-shadow, 0 0 transparent),
    var(--tw-shadow);
}
.dark .shadow-stroke:after {
  --tw-shadow: inset 0 0 0 1px hsla(0, 0%, 100%, 0.3);
  --tw-shadow-colored: inset 0 0 0 1px var(--tw-shadow-color);
}

.assistant-item {
  position: relative;
}

.assistant-item:after {
  --tw-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25);
  --tw-shadow-colored: inset 0 0 0 1px var(--tw-shadow-color);
  border-radius: 9999px;
  bottom: 0;
  content: '';
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  box-shadow:
    0 0 transparent,
    0 0 transparent,
    var(--tw-shadow);
  box-shadow:
    var(--tw-ring-offset-shadow, 0 0 transparent), var(--tw-ring-shadow, 0 0 transparent),
    var(--tw-shadow);
}

.dark .assistant-item:after {
  --tw-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25);
  --tw-shadow-colored: inset 0 0 0 1px var(--tw-shadow-color);
}

.result-streaming > :not(ol):not(ul):not(pre):last-child:after,
.result-streaming > pre:last-child code:after {
  display: inline-block;
  content: '⬤';
  width: 12px;
  height: 12px;
  font-family:
    system-ui,
    Inter,
    Söhne Circle,
    -apple-system,
    Segoe UI,
    Roboto,
    Ubuntu,
    Cantarell,
    Noto Sans,
    sans-serif;
  line-height: normal;
  margin-left: 0.25rem;
  vertical-align: middle;
  font-size: 0.5rem;
}

@supports (selector(:has(*))) {
  .result-streaming > :is(ul, ol):last-child > li:last-child:not(:has(> :is(ul, ol, pre))):after {
    content: '⬤';
    font-family:
      system-ui,
      Inter,
      Söhne Circle,
      -apple-system,
      Segoe UI,
      Roboto,
      Ubuntu,
      Cantarell,
      Noto Sans,
      sans-serif;
    line-height: normal;
    margin-left: 0.25rem;
    vertical-align: middle;
    font-size: 0.5rem;
    display: inline-block;
    width: 12px;
    height: 12px;
  }
}

@supports not (selector(:has(*))) {
  .result-streaming > ol:last-child > li:last-child:after,
  .result-streaming > ul:last-child > li:last-child:after {
    content: '⬤';
    font-family:
      system-ui,
      Inter,
      Söhne Circle,
      -apple-system,
      Segoe UI,
      Roboto,
      Ubuntu,
      Cantarell,
      Noto Sans,
      sans-serif;
    line-height: normal;
    margin-left: 0.25rem;
    vertical-align: middle;
    font-size: 0.5rem;
    display: inline-block;
    width: 12px;
    height: 12px;
  }

  .result-streaming > ol:last-child > li:last-child > :is(ul, ol, pre) ~ :after,
  .result-streaming > ul:last-child > li:last-child > :is(ul, ol, pre) ~ :after {
    display: none;
  }

  .result-streaming > ol:last-child > li:last-child > pre:last-child code:after,
  .result-streaming > ul:last-child > li:last-child > pre:last-child code:after {
    display: inline-block;
  }
}

/* Remove cursors when streaming is complete */
.result-streaming:not(.submitting) :is(ul, ol) li:after {
  display: none !important;
}

.webkit-dark-styles,
.webkit-dark-styles:focus {
  background-clip: content-box;
  -webkit-box-shadow: 0 0 0 50vh #fff inset;
}

.dark .webkit-dark-styles,
.dark .webkit-dark-styles:focus {
  -webkit-text-fill-color: #fff;
  background-clip: content-box;
  -webkit-box-shadow: 0 0 0 50vh #0d0d0d inset;
}

/* Ordered Listing */
.prose :where(ol[type='A']):not(:where([class~='not-prose'] *)) {
  list-style-type: upper-alpha;
}
.prose :where(ol[type='a']):not(:where([class~='not-prose'] *)) {
  list-style-type: lower-alpha;
}
.prose :where(ol[type='A s']):not(:where([class~='not-prose'] *)) {
  list-style-type: upper-alpha;
}
.prose :where(ol[type='a s']):not(:where([class~='not-prose'] *)) {
  list-style-type: lower-alpha;
}
.prose :where(ol[type='I']):not(:where([class~='not-prose'] *)) {
  list-style-type: upper-roman;
}
.prose :where(ol[type='i']):not(:where([class~='not-prose'] *)) {
  list-style-type: lower-roman;
}
.prose :where(ol[type='I s']):not(:where([class~='not-prose'] *)) {
  list-style-type: upper-roman;
}
.prose :where(ol[type='i s']):not(:where([class~='not-prose'] *)) {
  list-style-type: lower-roman;
}
.prose :where(ol[type='1']):not(:where([class~='not-prose'] *)) {
  list-style-type: decimal;
}
.prose :where(.prose > ol > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose :where(.prose > ol > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.25em;
}
.prose :where(ul ul, ul ol, ol ul, ol ol):not(:where([class~='not-prose'] *)) {
  margin-bottom: 0.75em;
  margin-top: 0.75em;
}
.prose-sm :where(.prose > ol > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 1.1428571em;
}
.prose-sm :where(.prose > ol > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.1428571em;
}
.prose-base :where(.prose > ol > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 0;
}
.prose-base :where(.prose > ol > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.25em;
}
.prose-lg :where(.prose > ol > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 1.3333333em;
}
.prose-lg :where(.prose > ol > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.3333333em;
}
.prose-xl :where(.prose > ol > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 1.2em;
}
.prose-xl :where(.prose > ol > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.2em;
}
.prose-2xl :where(.prose > ol > li > :first-child):not(:where([class~='not-prose'] *)) {
  margin-top: 1.3333333em;
}
.prose-2xl :where(.prose > ol > li > :last-child):not(:where([class~='not-prose'] *)) {
  margin-bottom: 1.3333333em;
}

/* Base styles for lists */
.prose ol,
.prose ul,
.markdown ol,
.markdown ul {
  list-style-position: outside;
  margin-top: 1em;
  margin-bottom: 1em;
  padding-left: 1em;
}

.prose li,
.markdown li {
  margin-bottom: 0.5em;
  margin-top: 0.5em;
}

/* Ordered lists */
.prose ol,
.markdown ol {
  list-style-type: decimal;
}

.prose ol > li,
.markdown ol > li {
  position: relative;
  padding-left: 0.375em;
}

.prose ol > li::marker,
.markdown ol > li::marker {
  color: var(--tw-prose-counters);
  font-weight: 400;
}

/* Nested ordered lists */
.prose ol ol,
.markdown ol ol {
  list-style-type: lower-alpha;
}

.prose ol ol ol,
.markdown ol ol ol {
  list-style-type: lower-roman;
}

/* Unordered lists */
.prose ul,
.markdown ul {
  list-style-type: disc;
}

.prose ul > li,
.markdown ul > li {
  padding-left: 0.375em;
}

.prose ul > li::marker,
.markdown ul > li::marker {
  color: var(--tw-prose-bullets);
}

/* Nested unordered lists */
.prose ul ul,
.markdown ul ul {
  list-style-type: circle;
}

.prose ul ul ul,
.markdown ul ul ul {
  list-style-type: square;
}

/* Nested lists */
.prose ol ol,
.prose ul ul,
.prose ul ol,
.prose ol ul,
.markdown ol ol,
.markdown ul ul,
.markdown ul ol,
.markdown ol ul {
  margin-top: 0.75em;
  margin-bottom: 0.75em;
}

.prose > ul > li > *:last-child,
.prose > ol > li > *:last-child,
.markdown > ul > li > *:last-child,
.markdown > ol > li > *:last-child {
  margin-bottom: 1.25em;
}

/* Ensure proper marker color */
.prose li::marker,
.markdown li::marker {
  color: currentColor;
}

/* Keyframes */

@keyframes slideFromLeftToRightAndFade {
  0% {
    opacity: 0;
    transform: translateX(-10%);
  }
  20% {
    opacity: 1;
    transform: translateX(0);
  }
  70% {
    opacity: 1;
    transform: translateX(0);
  }
  75% {
    opacity: 1;
    transform: translateX(10%);
  }
  80% {
    opacity: 0;
    transform: translateX(20%);
  }
  85%,
  100% {
    opacity: 0;
    transform: translateX(30%);
  }
}

.slide-from-left {
  animation: slideFromLeftToRightAndFade 2s ease-in-out infinite;
}

@keyframes slideDownAndFadeOut {
  0% {
    opacity: 1;
    transform: translateY(-10%);
  }
  20% {
    opacity: 1;
    transform: translateY(0);
  }
  70% {
    opacity: 1;
    transform: translateY(0);
  }
  75% {
    opacity: 1;
    transform: translateY(10%);
  }
  80% {
    opacity: 0;
    transform: translateY(20%);
  }
  85%,
  100% {
    opacity: 0;
    transform: translateY(30%);
  }
}

.slide-to-down {
  animation: slideDownAndFadeOut 2s ease-in-out infinite;
}

@keyframes rotateAdjustAndBack {
  0% {
    transform: rotate(-33deg) scale(1);
  }
  5% {
    transform: rotate(67deg) scale(1);
  }
  6%,
  20% {
    transform: rotate(57deg) scale(1);
  }
  22% {
    transform: rotate(65deg) scale(1);
  }
  26%,
  40% {
    transform: rotate(-33deg) scale(1);
  }
  42% {
    transform: rotate(-40deg) scale(1);
  }
  45%,
  75% {
    transform: rotate(30deg) scale(0.7);
  }
  77%,
  85% {
    transform: rotate(57deg) scale(1);
  }
  87% {
    transform: rotate(65deg) scale(1);
  }
  90%,
  100% {
    transform: rotate(-33deg) scale(1);
  }
}

.rotate-adjust-and-back {
  animation: rotateAdjustAndBack 10s ease-in-out infinite;
  transform-origin: 50% 50%;
}

@keyframes moonRise {
  0% {
    transform: translate(4px, 1px) rotate(-45deg);
    opacity: 0;
  }
  10% {
    transform: translate(4px, 1px) rotate(-45deg);
    opacity: 0;
  }
  20% {
    transform: translate(0, 0px) rotate(34deg);
    opacity: 1;
  }
  50% {
    transform: translate(0, 0px) rotate(34deg);
    opacity: 1;
  }
  60%,
  100% {
    transform: translate(0, 0px) rotate(34deg);
    opacity: 1;
  }
}

.moon-rise {
  animation: moonRise 4s ease-in-out infinite;
  transform-origin: 45% 50%;
}

@keyframes moveUp {
  0% {
    transform: translateY(0.5px);
    opacity: 0.8;
  }
  10% {
    transform: translateY(0.5px);
    opacity: 1;
  }
  20% {
    transform: translateY(0px);
    opacity: 1;
  }
  50% {
    transform: translateY(0px);
    opacity: 1;
  }
  60%,
  100% {
    transform: translateY(0px);
    opacity: 1;
  }
}

.move-up {
  animation: moveUp 4s ease-in-out infinite;
}

.message-content {
  font-size: var(--markdown-font-size, var(--font-size-base));
  line-height: 1.75;
}

.message-content pre code {
  font-size: calc(0.85 * var(--markdown-font-size, var(--font-size-base)));
}

.message-content pre {
  font-size: var(--markdown-font-size, var(--font-size-base));
}

.code-analyze-block pre code,
.code-analyze-block .overflow-y-auto code {
  font-size: calc(0.85 * var(--markdown-font-size, var(--font-size-base)));
}

.code-analyze-block pre,
.code-analyze-block .overflow-y-auto {
  font-size: var(--markdown-font-size, var(--font-size-base));
}

.progress-text-wrapper {
  font-size: var(--markdown-font-size, var(--font-size-base));
  line-height: calc(1.25 * var(--markdown-font-size, var(--font-size-base)));
}

.progress-text-content {
  font-size: inherit;
  line-height: inherit;
}

.progress-text-wrapper button {
  font-size: inherit;
  line-height: inherit;
}

.tooltip {
  z-index: 50;
  cursor: pointer;
  border-radius: 0.275rem;
  background-color: var(--surface-primary);
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
  padding-left: 0.5rem;
  padding-right: 0.5rem;
  font-size: 1rem;
  line-height: 1.5rem;
  color: black;
  box-shadow: 0 2px 4px 0 rgb(0 0 0 / 0.25);
}

.tooltip:where(.dark, .dark *) {
  background-color: var(--surface-primary);
  color: white;
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.35);
}

:focus {
  outline: none;
}

:focus-visible {
  outline: 2px solid #000;
  outline-offset: 2px;
}

.dark :focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.popover-ui {
  display: flex;
  max-height: min(var(--popover-available-height, 1700px), 1700px);
  flex-direction: column;
  overflow: auto;
  overscroll-behavior: contain;
  border-radius: 1rem;
  border-width: 1px;
  border-style: solid;
  border-color: var(--border-light);
  background-color: var(--surface-primary);
  padding: 0.5rem;
  color: var(--text-primary);
  box-shadow:
    0 10px 15px -3px rgb(0 0 0 / 0.1),
    0 4px 6px -4px rgb(0 0 0 / 0.1);
  transform-origin: top;
  opacity: 0;
  transition-property: opacity, scale, translate;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
  scale: 0.95;
  translate: 0 -0.5rem;
  margin-top: 4px;
  margin-right: -2px;
}

.popover-ui:focus-visible,
.popover-ui[data-focus-visible] {
  outline: var(--bg-surface-hover);
  outline-offset: -1px;
}

.popover-ui:where(.dark, .dark *) {
  background-color: var(--surface-secondary);
  color: var(--text-secondary);
  box-shadow:
    0 10px 15px -3px rgb(0 0 0 / 0.25),
    0 4px 6px -4px rgb(0 0 0 / 0.1);
}

.select-item {
  display: flex;
  cursor: pointer;
  scroll-margin: 0.5rem;
  align-items: center;
  gap: 0.5rem;
  border-radius: 0.5rem;
  padding: 0.5rem;
  outline: none !important;
}

.select-item[aria-disabled='true'] {
  opacity: 0.5;
}

.select-item[data-active-item] {
  background-color: var(--surface-hover);
  color: var(--text-primary);
}

.popover-ui[data-enter] {
  opacity: 1;
  scale: 1;
  translate: 0;
}

.animate-popover {
  transform-origin: top;
  opacity: 0;
  transition:
    opacity 150ms cubic-bezier(0.4, 0, 0.2, 1),
    transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
  transform: scale(0.95) translateY(-0.5rem);
}

.animate-popover[data-enter] {
  opacity: 1;
  transform: scale(1) translateY(0);
}

.animate-popover-left {
  transform-origin: left;
  opacity: 0;
  transition:
    opacity 150ms cubic-bezier(0.4, 0, 0.2, 1),
    transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
  transform: scale(0.95) translateX(-0.5rem);
}

.animate-popover-left[data-enter] {
  opacity: 1;
  transform: scale(1) translateX(0);
}

/** Note: ensure KaTeX can spread across visible space */
.message-content pre:has(> span.katex) {
  overflow: visible !important;
  height: auto !important;
  max-height: none !important;
}

/** AnimatedSearchInput style */

@keyframes gradient-x {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}

.animate-gradient-x {
  background-size: 200% 200%;
  animation: gradient-x 15s ease infinite;
}

.animate-pulse-subtle {
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

.animate-pulse-slow {
  animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.animate-fadeIn {
  animation: fadeIn 0.5s ease-out forwards;
}

.scale-98 {
  transform: scale(0.98);
}

/* Chat Badges Animation */

@keyframes ios-wiggle {
  0% {
    transform: rotate(-1deg);
  }
  50% {
    transform: rotate(1deg);
  }
  100% {
    transform: rotate(-1deg);
  }
}

.ios-wiggle {
  animation: ios-wiggle 0.2s ease-in-out infinite;
}

.ghost-badge {
  transition:
    left 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94),
    top 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

.badge-icon {
  transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

@keyframes shimmer {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}

.shimmer {
  display: inline-block;
  position: relative;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.8) 25%,
    rgba(179, 179, 179, 0.25) 50%,
    rgba(255, 255, 255, 0.8) 75%
  );
  background-size: 200% 100%;
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shimmer 4s linear infinite;
}

:global(.dark) .shimmer {
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255) 25%,
    rgba(129, 130, 134, 0.18) 50%,
    rgb(255, 255, 255) 75%
  );
  background-size: 200% 100%;
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shimmer 4s linear infinite;
}

.custom-style-2 {
  padding: 12px;
}


주요 내용은 다음과 같습니다.

  • Tailwind CSS 임포트: @tailwind base;, @tailwind components;, @tailwind utilities;를 통해 Tailwind CSS의 기본 스타일, 컴포넌트 스타일, 유틸리티 클래스를 가져오고 있습니다.
  • 커스텀 변수 (:root): --white, --black, --gray-20부터 --gray-900까지 다양한 회색 톤, 그리고 --green-50부터 --green-800까지 다양한 녹색 톤의 색상 변수를 정의하여 재사용성을 높였습니다.
  • 애니메이션 정의:
    • fadeIn: 요소가 투명도 0에서 1로 나타나고 아래에서 위로(translateY) 이동하는 페이드인 효과를 정의합니다. .animate-fadeIn 클래스가 이를 적용합니다.
    • ios-wiggle: iOS 아이콘처럼 좌우로 미세하게 흔들리는 효과를 정의합니다. .ios-wiggle 클래스가 이를 적용합니다.
    • shimmer: 배경색이 왼쪽에서 오른쪽으로 이동하는 듯한 반짝이는(shimmer) 효과를 정의합니다. .shimmer 클래스가 이를 적용합니다.
  • 클래스 정의:
    • .scale-98: 요소를 0.98배로 축소하는 변형을 적용합니다.
    • .ghost-badge, .badge-icon: transition 속성을 사용하여 left, top, transform 속성 변경 시 부드러운 애니메이션 효과를 적용합니다.

요약하자면, 이 CSS 파일은 웹 페이지의 색상, 폰트, 레이아웃 등 전반적인 디자인을 제어하고, 특히 요소들이 부드럽게 나타나거나 움직이는 등의 동적인 시각 효과를 부여하는 데 사용됩니다.

댓글

이 블로그의 인기 게시물

아파치 보안관련 기본설정

티베로 이관 작업 절차

윈도우 네트워크 리소스 사용권한 오류