<html lang="en">
<head></head>
<body>

<form id="mainForm" method="post" action="https://stackblitz.com/run" target="_self">
<input type="hidden" name="project[files][README.md]" value="# SolidStart

Everything you need to build a Solid project, powered by [`solid-start`](https://start.solidjs.com);

## Creating a project

```bash
# create a new project in the current directory
npm init solid@latest

# create a new project in my-app
npm init solid@latest my-app
```

## Developing

Once you&#39;ve created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:

```bash
npm run dev

# or start the server and open the app in a new browser tab
npm run dev -- --open
```

## Building

Solid apps are built with _presets_, which optimise your project for deployment to different environments.

By default, `npm run build` will generate a Node app that you can run with `npm start`. To use a different preset, add it to the `devDependencies` in `package.json` and specify in your `app.config.js`.
">
<input type="hidden" name="project[files][app.config.ts]" value="import { defineConfig } from &quot;@solidjs/start/config&quot;;

export default defineConfig({});
">
<input type="hidden" name="project[files][package.json]" value="{&quot;name&quot;:&quot;example-notes&quot;,&quot;type&quot;:&quot;module&quot;,&quot;scripts&quot;:{&quot;dev&quot;:&quot;vinxi dev&quot;,&quot;build&quot;:&quot;vinxi build&quot;,&quot;start&quot;:&quot;vinxi start&quot;},&quot;dependencies&quot;:{&quot;@solidjs/router&quot;:&quot;^0.15.0&quot;,&quot;@solidjs/start&quot;:&quot;https://pkg.pr.new/solidjs/solid-start/@solidjs/start@e2d3bd2&quot;,&quot;date-fns&quot;:&quot;^3.6.0&quot;,&quot;solid-js&quot;:&quot;^1.9.5&quot;,&quot;marked&quot;:&quot;^12.0.1&quot;,&quot;unstorage&quot;:&quot;1.10.2&quot;,&quot;vinxi&quot;:&quot;^0.5.3&quot;},&quot;engines&quot;:{&quot;node&quot;:&quot;&gt;=22&quot;}}">
<input type="hidden" name="project[files][tsconfig.json]" value="{
  &quot;compilerOptions&quot;: {
    &quot;target&quot;: &quot;ESNext&quot;,
    &quot;module&quot;: &quot;ESNext&quot;,
    &quot;moduleResolution&quot;: &quot;bundler&quot;,
    &quot;allowSyntheticDefaultImports&quot;: true,
    &quot;esModuleInterop&quot;: true,
    &quot;jsx&quot;: &quot;preserve&quot;,
    &quot;jsxImportSource&quot;: &quot;solid-js&quot;,
    &quot;allowJs&quot;: true,
    &quot;strict&quot;: true,
    &quot;noEmit&quot;: true,
    &quot;types&quot;: [&quot;vinxi/types/client&quot;],
    &quot;isolatedModules&quot;: true,
    &quot;paths&quot;: {
      &quot;~/*&quot;: [&quot;./src/*&quot;]
    }
  }
}
">
<input type="hidden" name="project[files][public/checkmark.svg]" value="&lt;svg width=&quot;14&quot; height=&quot;10&quot; viewBox=&quot;0 0 14 10&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;path d=&quot;M0.666504 5.17139L4.77457 9.27954L13.3334 0.720551&quot; stroke=&quot;white&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;/&gt;
&lt;/svg&gt;
">
<input type="hidden" name="project[files][public/chevron-down.svg]" value="&lt;svg width=&quot;10&quot; height=&quot;6&quot; viewBox=&quot;0 0 10 6&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;path d=&quot;M9.5 5.25L5 0.75L0.5 5.25&quot; stroke=&quot;#8A8D91&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;/&gt;
&lt;/svg&gt;
">
<input type="hidden" name="project[files][public/chevron-up.svg]" value="&lt;svg width=&quot;10&quot; height=&quot;6&quot; viewBox=&quot;0 0 10 6&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;path d=&quot;M9.5 0.75L5 5.25L0.5 0.75&quot; stroke=&quot;#8A8D91&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;/&gt;
&lt;/svg&gt;
">
<input type="hidden" name="project[files][public/cross.svg]" value="&lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 12 12&quot; fill=&quot;none&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
&lt;path d=&quot;M 12 0 L 0 12 M 0 0 L 12 12&quot; stroke=&quot;#BD0D2A&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot;/&gt;
&lt;/svg&gt;
">
<input type="hidden" name="project[files][public/favicon.ico]" value="https://pkg.pr.new/template/99bd230d-9924-4ea9-ad87-01ed2c356764">
<input type="hidden" name="project[files][public/logo.svg]" value="&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; viewBox=&quot;0 0 166 155.3&quot;&gt;&lt;defs&gt;&lt;linearGradient id=&quot;a&quot; gradientUnits=&quot;userSpaceOnUse&quot; x1=&quot;27.5&quot; y1=&quot;3&quot; x2=&quot;152&quot; y2=&quot;63.5&quot;&gt;&lt;stop offset=&quot;.1&quot; stop-color=&quot;#76b3e1&quot;/&gt;&lt;stop offset=&quot;.3&quot; stop-color=&quot;#dcf2fd&quot;/&gt;&lt;stop offset=&quot;1&quot; stop-color=&quot;#76b3e1&quot;/&gt;&lt;/linearGradient&gt;&lt;linearGradient id=&quot;b&quot; gradientUnits=&quot;userSpaceOnUse&quot; x1=&quot;95.8&quot; y1=&quot;32.6&quot; x2=&quot;74&quot; y2=&quot;105.2&quot;&gt;&lt;stop offset=&quot;0&quot; stop-color=&quot;#76b3e1&quot;/&gt;&lt;stop offset=&quot;.5&quot; stop-color=&quot;#4377bb&quot;/&gt;&lt;stop offset=&quot;1&quot; stop-color=&quot;#1f3b77&quot;/&gt;&lt;/linearGradient&gt;&lt;linearGradient id=&quot;c&quot; gradientUnits=&quot;userSpaceOnUse&quot; x1=&quot;18.4&quot; y1=&quot;64.2&quot; x2=&quot;144.3&quot; y2=&quot;149.8&quot;&gt;&lt;stop offset=&quot;0&quot; stop-color=&quot;#315aa9&quot;/&gt;&lt;stop offset=&quot;.5&quot; stop-color=&quot;#518ac8&quot;/&gt;&lt;stop offset=&quot;1&quot; stop-color=&quot;#315aa9&quot;/&gt;&lt;/linearGradient&gt;&lt;linearGradient id=&quot;d&quot; gradientUnits=&quot;userSpaceOnUse&quot; x1=&quot;75.2&quot; y1=&quot;74.5&quot; x2=&quot;24.4&quot; y2=&quot;260.8&quot;&gt;&lt;stop offset=&quot;0&quot; stop-color=&quot;#4377bb&quot;/&gt;&lt;stop offset=&quot;.5&quot; stop-color=&quot;#1a336b&quot;/&gt;&lt;stop offset=&quot;1&quot; stop-color=&quot;#1a336b&quot;/&gt;&lt;/linearGradient&gt;&lt;/defs&gt;&lt;path d=&quot;M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z&quot; fill=&quot;#76b3e1&quot;/&gt;&lt;path d=&quot;M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z&quot; opacity=&quot;.3&quot; fill=&quot;url(#a)&quot;/&gt;&lt;path d=&quot;M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z&quot; fill=&quot;#518ac8&quot;/&gt;&lt;path d=&quot;M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z&quot; opacity=&quot;.3&quot; fill=&quot;url(#b)&quot;/&gt;&lt;path d=&quot;M134 80a45 45 0 00-48-15L24 85 4 120l112 19 20-36c4-7 3-15-2-23z&quot; fill=&quot;url(#c)&quot;/&gt;&lt;path d=&quot;M114 115a45 45 0 00-48-15L4 120s53 40 94 30l3-1c17-5 23-21 13-34z&quot; fill=&quot;url(#d)&quot;/&gt;&lt;/svg&gt;">
<input type="hidden" name="project[files][src/app.css]" value="/* -------------------------------- CSSRESET --------------------------------*/
/* CSS Reset adapted from https://dev.to/hankchizljaw/a-modern-css-reset-6p3 */
/* Box sizing rules */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Remove default padding */
ul[class],
ol[class] {
  padding: 0;
}

.sidebar-note-list-item &gt; solid-children {
  z-index: 1;
}

solid-island, solid-children, outlet-wrapper {
  display: contents;
}

.note-preview {
  word-break: break-word;
}

/* Remove default margin */
body,
h1,
h2,
h3,
h4,
p,
ul[class],
ol[class],
li,
figure,
figcaption,
blockquote,
dl,
dd {
  margin: 0;
}

/* Set core body defaults */
body {
  min-height: 100vh;
  scroll-behavior: smooth;
  text-rendering: optimizeSpeed;
  line-height: 1.5;
}

/* Remove list styles on ul, ol elements with a class attribute */
ul[class],
ol[class] {
  list-style: none;
}

/* A elements that don&#39;t have a class get default styles */
a:not([class]) {
  text-decoration-skip-ink: auto;
}

/* Make images easier to work with */
img {
  max-width: 100%;
  display: block;
}

/* Natural flow and rhythm in articles by default */
article &gt; * + * {
  margin-block-start: 1em;
}

/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
  font: inherit;
}

/* Remove all animations and transitions for people that prefer not to see them */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
/* -------------------------------- /CSSRESET --------------------------------*/

:root {
  /* Colors */
  --main-border-color: #ddd;
  --primary-border: #037dba;
  --gray-20: #404346;
  --gray-60: #8a8d91;
  --gray-70: #bcc0c4;
  --gray-80: #c9ccd1;
  --gray-90: #e4e6eb;
  --gray-95: #f0f2f5;
  --gray-100: #f5f7fa;
  --primary-blue: #037dba;
  --secondary-blue: #0396df;
  --tertiary-blue: #c6efff;
  --flash-blue: #4cf7ff;
  --outline-blue: rgba(4, 164, 244, 0.6);
  --navy-blue: #035e8c;
  --red-25: #bd0d2a;
  --secondary-text: #65676b;
  --secondary-text-dark: #dde1e9;
  --white: #fff;
  --yellow: #fffae1;

  --outline-box-shadow: 0 0 0 2px var(--outline-blue);
  --outline-box-shadow-contrast: 0 0 0 2px var(--navy-blue);

  /* Fonts */
  --sans-serif: -apple-system, system-ui, BlinkMacSystemFont, &#39;Segoe UI&#39;, Roboto,
    Ubuntu, Helvetica, sans-serif;
  --monospace: Menlo, Consolas, Monaco, Liberation Mono, Lucida Console,
    monospace;
}

html {
  font-size: 100%;
}

body {
  font-family: var(--sans-serif);
  background: var(--gray-100);
  font-weight: 400;
  line-height: 1.75;
}

h1,
h2,
h3,
h4,
h5 {
  margin: 0;
  font-weight: 700;
  line-height: 1.3;
}

h1 {
  font-size: 3.052rem;
}
h2 {
  font-size: 2.441rem;
}
h3 {
  font-size: 1.953rem;
}
h4 {
  font-size: 1.563rem;
}
h5 {
  font-size: 1.25rem;
}
small,
.text_small {
  font-size: 0.8rem;
}
pre,
code {
  font-family: var(--monospace);
  border-radius: 6px;
}
pre {
  background: var(--gray-95);
  padding: 12px;
  line-height: 1.5;
}
code {
  background: var(--yellow);
  padding: 0 3px;
  font-size: 0.94rem;
  word-break: break-word;
}
pre code {
  background: none;
}
a {
  color: var(--primary-blue);
}

.text-with-markdown h1,
.text-with-markdown h2,
.text-with-markdown h3,
.text-with-markdown h4,
.text-with-markdown h5 {
  margin-block: 2rem 0.7rem;
  margin-inline: 0;
}

.text-with-markdown blockquote {
  font-style: italic;
  color: var(--gray-20);
  border-left: 3px solid var(--gray-80);
  padding-left: 10px;
}

hr {
  border: 0;
  height: 0;
  border-top: 1px solid rgba(0, 0, 0, 0.1);
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}

/* ---------------------------------------------------------------------------*/
.main {
  display: flex;
  height: 100vh;
  width: 100%;
  overflow: hidden;
}

.col {
  height: 100%;
}
.col:last-child {
  flex-grow: 1;
}

.logo {
  height: 20px;
  width: 22px;
  margin-inline-end: 10px;
}

.edit-button {
  border-radius: 100px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 6px 20px 8px;
  cursor: pointer;
  font-weight: 700;
  outline-style: none;
}

.dark-mode-toggle {
  border-radius: 100px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 6px 20px ;
  cursor: pointer;
  font-weight: 700;
  outline-style: none;
  background: var(--primary-blue);
  color: var(--white);
  border: none;
  margin-inline-start: 6px;
  transition: all 0.2s ease-in-out;
}
.edit-button--solid {
  background: var(--primary-blue);
  color: var(--white);
  border: none;
  margin-inline-start: 6px;
  transition: all 0.2s ease-in-out;
}
.edit-button--solid:hover {
  background: var(--secondary-blue);
}
.edit-button--solid:focus {
  box-shadow: var(--outline-box-shadow-contrast);
}
.edit-button--outline {
  background: var(--white);
  color: var(--primary-blue);
  border: 1px solid var(--primary-blue);
  margin-inline-start: 12px;
  transition: all 0.1s ease-in-out;
}
.edit-button--outline:disabled {
  opacity: 0.5;
}
.edit-button--outline:hover:not([disabled]) {
  background: var(--primary-blue);
  color: var(--white);
}
.edit-button--outline:focus {
  box-shadow: var(--outline-box-shadow);
}

ul.notes-list {
  padding: 16px 0;
}
.notes-list &gt; li {
  padding: 0 16px;
}
.notes-empty {
  padding: 16px;
}

.sidebar {
  box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.1), 0px 2px 2px rgba(0, 0, 0, 0.1);
  overflow-y: scroll;
  z-index: 1000;
  flex-shrink: 0;
  max-width: 350px;
  min-width: 250px;
  width: 30%;
}
.light &gt; .sidebar {
  background: var(--white);
}
.dark .sidebar {
  background:#151d28;
}
.sidebar-header {
  letter-spacing: 0.15em;
  text-transform: uppercase;
  padding: 36px 16px 16px;
  display: flex;
  align-items: center;
}

.dark .sidebar-header {
  color: white;
}

.sidebar-menu {
  padding: 0 16px 16px;
  display: flex;
  justify-content: space-between;
}
.sidebar-menu &gt; .search {
  position: relative;
  flex-grow: 1;
}
.sidebar-note-list-item {
  position: relative;
  margin-bottom: 12px;
  padding: 16px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  max-height: 100px;
  transition: max-height 250ms ease-out;
  transform: scale(1);
  /* background-color: var(--gray-95); */
}
.sidebar-note-list-item.note-expanded {
  max-height: 300px;
  transition: max-height 0.5s ease;
}
.sidebar-note-list-item.flash {
  animation-name: flash;
  animation-duration: 0.6s;
}

.sidebar-note-open {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  z-index: 0;
  border: none;
  border-radius: 6px;
  text-align: start;
  background: var(--gray-95);
  cursor: pointer;
  outline-style: none;
  color: transparent;
  font-size: 0px;
}
.sidebar-note-open:focus {
  box-shadow: var(--outline-box-shadow);
}
.sidebar-note-open:hover {
  background: var(--gray-90);
}
.sidebar-note-header {
  z-index: 1;
  width: 85%;
  pointer-events: none;
}
.sidebar-note-header &gt; strong {
  display: block;
  font-size: 1.25rem;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sidebar-note-toggle-expand {
  z-index: 2;
  border-radius: 50%;
  height: 24px;
  border: 1px solid var(--gray-60);
  cursor: pointer;
  flex-shrink: 0;
  visibility: hidden;
  opacity: 0;
  cursor: default;
  transition: visibility 0s linear 20ms, opacity 300ms;
  outline-style: none;
}
.sidebar-note-toggle-expand:focus {
  box-shadow: var(--outline-box-shadow);
}
.sidebar-note-open:hover + .sidebar-note-toggle-expand,
.sidebar-note-open:focus + .sidebar-note-toggle-expand,
.sidebar-note-toggle-expand:hover,
.sidebar-note-toggle-expand:focus {
  visibility: visible;
  opacity: 1;
  transition: visibility 0s linear 0s, opacity 300ms;
}
.sidebar-note-toggle-expand img {
  width: 10px;
  height: 10px;
}

.sidebar-note-excerpt {
  pointer-events: none;
  z-index: 2;
  flex: 1 1 250px;
  position: relative;
  animation: slideIn 100ms;
}

.light &gt; .sidebar-note-excerpt {
  color: var(--secondary-text);
}

.dark &gt; .sidebar-note-excerpt {
  color: var(--secondary-text-dark);
} 

.search input {
  padding: 0 16px;
  border-radius: 100px;
  border: 1px solid var(--gray-90);
  width: 100%;
  height: 100%;
  outline-style: none;
}
.search input:focus {
  box-shadow: var(--outline-box-shadow);
}
.search .spinner {
  position: absolute;
  right: 10px;
  top: 10px;
}

.note-viewer {
  display: flex;
  align-items: center;
  justify-content: center;
}
.note {
  background: var(--white);
  box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1), 0px 0px 1px rgba(0, 0, 0, 0.1);
  border-radius: 8px;
  height: 95%;
  width: 95%;
  min-width: 400px;
  padding: 8%;
  overflow-y: auto;
}
.note--empty-state {
  margin-inline: 20px 20px;
}
.note-text--empty-state {
  font-size: 1.5rem;
}
.note-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap-reverse;
  margin-inline-start: -12px;
}
.note-menu {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-grow: 1;
}
.note-title {
  line-height: 1.3;
  flex-grow: 1;
  overflow-wrap: break-word;
  margin-inline-start: 12px;
}
.note-updated-at {
  color: var(--secondary-text);
  white-space: nowrap;
  margin-inline-start: 12px;
}
.note-preview {
  margin-block-start: 50px;
}

.note-editor {
  background: var(--white);
  display: flex;
  height: 100%;
  width: 100%;
  padding: 58px;
  overflow-y: auto;
}
.note-editor .label {
  margin-bottom: 20px;
}
.note-editor-form {
  display: flex;
  flex-direction: column;
  width: 400px;
  flex-shrink: 0;
  position: sticky;
  top: 0;
}
.note-editor-form input,
.note-editor-form textarea {
  background: none;
  border: 1px solid var(--gray-70);
  border-radius: 2px;
  font-family: var(--monospace);
  font-size: 0.8rem;
  padding: 12px;
  outline-style: none;
}
.note-editor-form input:focus,
.note-editor-form textarea:focus {
  box-shadow: var(--outline-box-shadow);
}
.note-editor-form input {
  height: 44px;
  margin-bottom: 16px;
}
.note-editor-form textarea {
  height: 100%;
  max-width: 400px;
}
.note-editor-menu {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  margin-bottom: 12px;
}
.note-editor-preview {
  margin-inline-start: 40px;
  width: 100%;
}
.note-editor-done,
.note-editor-delete {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-radius: 100px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 6px 20px 8px;
  cursor: pointer;
  font-weight: 700;
  margin-inline-start: 12px;
  outline-style: none;
  transition: all 0.2s ease-in-out;
}
.note-editor-done:disabled,
.note-editor-delete:disabled {
  opacity: 0.5;
}
.note-editor-done {
  border: none;
  background: var(--primary-blue);
  color: var(--white);
}
.note-editor-done:focus {
  box-shadow: var(--outline-box-shadow-contrast);
}
.note-editor-done:hover:not([disabled]) {
  background: var(--secondary-blue);
}
.note-editor-delete {
  border: 1px solid var(--red-25);
  background: var(--white);
  color: var(--red-25);
}
.note-editor-delete:focus {
  box-shadow: var(--outline-box-shadow);
}
.note-editor-delete:hover:not([disabled]) {
  background: var(--red-25);
  color: var(--white);
}
/* Hack to color our svg */
.note-editor-delete:hover:not([disabled]) img {
  filter: grayscale(1) invert(1) brightness(2);
}
.note-editor-done &gt; img {
  width: 14px;
}
.note-editor-delete &gt; img {
  width: 10px;
}
.note-editor-done &gt; img,
.note-editor-delete &gt; img {
  margin-inline-end: 12px;
}
.note-editor-done[disabled],
.note-editor-delete[disabled] {
  opacity: 0.5;
}

.label {
  display: inline-block;
  border-radius: 100px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 700;
  padding: 4px 14px;
}
.label--preview {
  background: rgba(38, 183, 255, 0.15);
  color: var(--primary-blue);
}

.text-with-markdown p {
  margin-bottom: 16px;
}
.text-with-markdown img {
  width: 100%;
}

/* https://codepen.io/mandelid/pen/vwKoe */
.spinner {
  display: inline-block;
  transition: opacity linear 0.1s;
  width: 20px;
  height: 20px;
  border: 3px solid rgba(80, 80, 80, 0.5);
  border-radius: 50%;
  border-top-color: #fff;
  animation: spin 1s ease-in-out infinite;
  opacity: 0;
}
.spinner--active {
  opacity: 1;
}

.skeleton::after {
  content: &#39;Loading...&#39;;
}
.skeleton {
  height: 100%;
  background-color: #eee;
  background-image: linear-gradient(90deg, #eee, #f5f5f5, #eee);
  background-size: 200px 100%;
  background-repeat: no-repeat;
  border-radius: 4px;
  display: block;
  line-height: 1;
  width: 100%;
  animation: shimmer 1.2s ease-in-out infinite;
  color: transparent;
}
.skeleton:first-of-type {
  margin: 0;
}
.skeleton--button {
  border-radius: 100px;
  padding: 6px 20px 8px;
  width: auto;
}
.v-stack + .v-stack {
  margin-block-start: 0.8em;
}

.offscreen {
  border: 0;
  clip: rect(0, 0, 0, 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  width: 1px;
  position: absolute;
}

/* ---------------------------------------------------------------------------*/
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes shimmer {
  0% {
    background-position: -200px 0;
  }
  100% {
    background-position: calc(200px + 100%) 0;
  }
}

@keyframes slideIn {
  0% {
    top: -10px;
    opacity: 0;
  }
  100% {
    top: 0;
    opacity: 1;
  }
}

@keyframes flash {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.05);
    opacity: 0.9;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}
">
<input type="hidden" name="project[files][src/app.tsx]" value="import { Router } from &quot;@solidjs/router&quot;;
import { FileRoutes } from &quot;@solidjs/start/router&quot;;
import { Suspense } from &quot;solid-js&quot;;
import EditButton from &quot;~/components/EditButton&quot;;
import NoteList from &quot;~/components/NoteList&quot;;
import { getNotes } from &quot;~/lib/api&quot;;
import &quot;./app.css&quot;;
import SearchField from &quot;./components/SearchField&quot;;

export default function App() {
  return (
    &lt;Router
      root={props =&gt; (
        &lt;div class=&quot;main&quot; $ServerOnly&gt;
          &lt;section class=&quot;col sidebar&quot;&gt;
            &lt;section class=&quot;sidebar-header&quot;&gt;
              &lt;a href=&quot;/&quot;&gt;
                &lt;img
                  class=&quot;logo&quot;
                  src=&quot;/logo.svg&quot;
                  width=&quot;22px&quot;
                  height=&quot;20px&quot;
                  alt=&quot;&quot;
                  role=&quot;presentation&quot;
                /&gt;
              &lt;/a&gt;
              &lt;strong&gt;Solid Notes&lt;/strong&gt;
            &lt;/section&gt;
            &lt;section class=&quot;sidebar-menu&quot; role=&quot;menubar&quot;&gt;
              &lt;SearchField /&gt;
              &lt;EditButton&gt;New&lt;/EditButton&gt;
            &lt;/section&gt;
            &lt;nav&gt;
              &lt;Suspense fallback=&quot;Loading Notes..&quot;&gt;
                &lt;NoteList searchText={props.location.query.searchText || &quot;&quot;} /&gt;
              &lt;/Suspense&gt;
            &lt;/nav&gt;
          &lt;/section&gt;
          &lt;section class=&quot;col note-viewer&quot;&gt;
            &lt;Suspense fallback=&quot;Loading Content&quot;&gt;{props.children}&lt;/Suspense&gt;
          &lt;/section&gt;
        &lt;/div&gt;
      )}
      rootLoad={({ location }) =&gt; getNotes(location.query.searchText || &quot;&quot;)}
    &gt;
      &lt;FileRoutes /&gt;
    &lt;/Router&gt;
  );
}
">
<input type="hidden" name="project[files][src/entry-client.tsx]" value="// @refresh reload
import { mount, StartClient } from &quot;@solidjs/start/client&quot;;

mount(() =&gt; &lt;StartClient /&gt;, document.getElementById(&quot;app&quot;)!);
">
<input type="hidden" name="project[files][src/entry-server.tsx]" value="// @refresh reload
import { createHandler, StartServer } from &quot;@solidjs/start/server&quot;;

export default createHandler(() =&gt; (
  &lt;StartServer
    document={({ assets, children, scripts }) =&gt; (
      &lt;html lang=&quot;en&quot;&gt;
        &lt;head&gt;
          &lt;meta charset=&quot;utf-8&quot; /&gt;
          &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot; /&gt;
          &lt;link rel=&quot;icon&quot; href=&quot;/favicon.ico&quot; /&gt;
          {assets}
        &lt;/head&gt;
        &lt;body&gt;
          &lt;div id=&quot;app&quot;&gt;{children}&lt;/div&gt;
          {scripts}
        &lt;/body&gt;
      &lt;/html&gt;
    )}
  /&gt;
));
">
<input type="hidden" name="project[files][src/global.d.ts]" value="/// &lt;reference types=&quot;@solidjs/start/env&quot; /&gt;
">
<input type="hidden" name="project[files][src/components/EditButton.tsx]" value="/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */
import type { JSX } from &quot;solid-js&quot;;

export default function EditButton(props: { noteId?: number; children: JSX.Element }) {
  const isDraft = !(&quot;noteId&quot; in props);
  return (
    &lt;a
      href={!isDraft ? `/notes/${props.noteId}/edit` : `/new`}
      class={[&quot;edit-button&quot;, isDraft ? &quot;edit-button--solid&quot; : &quot;edit-button--outline&quot;].join(&quot; &quot;)}
      role=&quot;menuitem&quot;
    &gt;
      {props.children}
    &lt;/a&gt;
  );
}
">
<input type="hidden" name="project[files][src/components/NoteEditor.tsx]" value="/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import { useSubmission } from &quot;@solidjs/router&quot;;
import { marked } from &quot;marked&quot;;
import { createSignal } from &quot;solid-js&quot;;
import { deleteNote, saveNote } from &quot;~/lib/api&quot;;

export default function NoteEditor(props: {
  noteId?: number;
  initialTitle: string;
  initialBody: string;
}) {
  const [title, setTitle] = createSignal(props.initialTitle);
  const [body, setBody] = createSignal(props.initialBody);
  const isSaving = useSubmission(saveNote);
  const isDeleting = useSubmission(deleteNote);
  const isDraft = props.noteId == null;

  return (
    &lt;div class=&quot;note-editor&quot;&gt;
      &lt;form
        action={saveNote.with(props.noteId)}
        method=&quot;post&quot;
        class=&quot;note-editor-form&quot;
        id=&quot;note-editor&quot;
        autocomplete=&quot;off&quot;
      &gt;
        &lt;label class=&quot;offscreen&quot; for=&quot;note-title-input&quot;&gt;
          Enter a title for your note
        &lt;/label&gt;
        &lt;input
          id=&quot;note-title-input&quot;
          type=&quot;text&quot;
          name=&quot;title&quot;
          placeholder=&quot;Title&quot;
          required={true}
          value={title()}
          onInput={e =&gt; {
            setTitle(e.currentTarget.value);
          }}
        /&gt;
        &lt;label class=&quot;offscreen&quot; for=&quot;note-body-input&quot;&gt;
          Enter the body for your note
        &lt;/label&gt;
        &lt;textarea
          name=&quot;body&quot;
          id=&quot;note-body-input&quot;
          textContent={body()}
          onInput={e =&gt; {
            setBody(e.currentTarget.value);
          }}
        /&gt;
      &lt;/form&gt;
      &lt;div class=&quot;note-editor-preview&quot;&gt;
        &lt;div class=&quot;note-editor-menu&quot; role=&quot;menubar&quot;&gt;
          &lt;button
            class=&quot;note-editor-done&quot;
            disabled={isSaving.pending}
            type=&quot;submit&quot;
            form=&quot;note-editor&quot;
            role=&quot;menuitem&quot;
          &gt;
            &lt;img src=&quot;/checkmark.svg&quot; width=&quot;14px&quot; height=&quot;10px&quot; alt=&quot;&quot; role=&quot;presentation&quot; /&gt;
            Done
          &lt;/button&gt;
          {!isDraft &amp;&amp; (
            &lt;form action={deleteNote.with(props.noteId!)} method=&quot;post&quot;&gt;
              &lt;button
                name=&quot;noteId&quot;
                class=&quot;note-editor-delete&quot;
                disabled={isDeleting.pending}
                type=&quot;submit&quot;
                role=&quot;menuitem&quot;
              &gt;
                &lt;img src=&quot;/cross.svg&quot; width=&quot;10px&quot; height=&quot;10px&quot; alt=&quot;&quot; role=&quot;presentation&quot; /&gt;
                Delete
              &lt;/button&gt;
            &lt;/form&gt;
          )}
        &lt;/div&gt;
        &lt;div class=&quot;label label--preview&quot; role=&quot;status&quot;&gt;
          Preview
        &lt;/div&gt;
        &lt;h1 class=&quot;note-title&quot;&gt;{title()}&lt;/h1&gt;
        &lt;div class=&quot;note-preview&quot;&gt;
          &lt;div class=&quot;text-with-markdown&quot; innerHTML={body() ? marked(body()) : &quot;&quot;} /&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
}
">
<input type="hidden" name="project[files][src/components/NoteList.tsx]" value="import { createAsyncStore } from &quot;@solidjs/router&quot;;
import { For, Show } from &quot;solid-js&quot;;
import { getNotes } from &quot;~/lib/api&quot;;
import SidebarNote from &quot;./SidebarNote&quot;;

export default function NoteList(props: { searchText: string }) {
  const notes = createAsyncStore(() =&gt; getNotes(props.searchText));

  return (
      &lt;Show
        when={notes()?.length}
        fallback={
          &lt;div class=&quot;notes-empty&quot;&gt;
            {props.searchText
              ? `Couldn&#39;t find any notes titled &quot;${props.searchText}&quot;.`
              : &quot;No notes created yet!&quot;}
          &lt;/div&gt;
        }
      &gt;
        &lt;ul class=&quot;notes-list&quot;&gt;
          &lt;For each={notes()}&gt;
            {note =&gt; (
              &lt;li&gt;
                &lt;SidebarNote note={note} /&gt;
              &lt;/li&gt;
            )}
          &lt;/For&gt;
        &lt;/ul&gt;
      &lt;/Show&gt;
  );
}
">
<input type="hidden" name="project[files][src/components/SearchField.tsx]" value="/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */
import { useSearchParams } from &quot;@solidjs/router&quot;;
import { useTransition } from &quot;solid-js&quot;;

export default function SearchField() {
  const [isSearching] = useTransition();
  const [search, setParams] = useSearchParams();
  return (
    &lt;form class=&quot;search&quot; role=&quot;search&quot; onSubmit={e =&gt; e.preventDefault()} $ServerOnly&gt;
      &lt;label class=&quot;offscreen&quot; for=&quot;sidebar-search-input&quot;&gt;
        Search for a note by title
      &lt;/label&gt;
      &lt;input
        id=&quot;sidebar-search-input&quot;
        placeholder=&quot;Search&quot;
        value={search.searchText || &quot;&quot;}
        onInput={e =&gt; {
          setParams({
            searchText: e.target.value
          });
        }}
      /&gt;
      &lt;div
        class={[&quot;spinner&quot;, isSearching() &amp;&amp; &quot;spinner--active&quot;].join(&quot; &quot;)}
        role=&quot;progressbar&quot;
        aria-busy={isSearching() ? &quot;true&quot; : &quot;false&quot;}
      /&gt;
    &lt;/form&gt;
  );
}
">
<input type="hidden" name="project[files][src/components/SidebarNote.tsx]" value="/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */

import { useLocation } from &quot;@solidjs/router&quot;;
import { createEffect, createSignal, Show, useTransition } from &quot;solid-js&quot;;
import { Note } from &quot;~/lib/types&quot;;

export default function SidebarNote(props: { note: Note }) {
  const location = useLocation();
  const [isPending] = useTransition();
  const [isExpanded, setIsExpanded] = createSignal(false);
  const isActive = () =&gt; {
    return location.pathname.startsWith(`/notes/${props.note.id}`);
  };
  let itemRef!: HTMLDivElement;

  let title = props.note.title;
  createEffect(() =&gt; {
    if (props.note.title !== title) {
      title = props.note.title;
      itemRef.classList.add(&quot;flash&quot;);
    }
  });

  return (
    &lt;div
      ref={itemRef}
      onAnimationEnd={() =&gt; {
        itemRef.classList.remove(&quot;flash&quot;);
      }}
      style={{
        color: &quot;black&quot;
      }}
      class={[&quot;sidebar-note-list-item&quot;, isExpanded() ? &quot;note-expanded&quot; : &quot;&quot;].join(&quot; &quot;)}
    &gt;
      &lt;header class=&quot;sidebar-note-header&quot;&gt;
        &lt;strong&gt;{props.note.title}&lt;/strong&gt;
        &lt;small&gt;{props.note.updatedAt}&lt;/small&gt;
      &lt;/header&gt;
      &lt;a
        href={`/notes/${props.note.id}`}
        class=&quot;sidebar-note-open&quot;
        style={{
          &quot;background-color&quot;: isPending()
            ? &quot;var(--gray-80)&quot;
            : isActive()
            ? &quot;var(--tertiary-blue)&quot;
            : &quot;&quot;,
          border: isActive() ? &quot;1px solid var(--primary-border)&quot; : &quot;1px solid transparent&quot;
        }}
      &gt;
        Open note for preview
      &lt;/a&gt;
      &lt;button
        class=&quot;sidebar-note-toggle-expand&quot;
        onClick={e =&gt; {
          e.stopPropagation();
          setIsExpanded(isExpanded =&gt; !isExpanded);
        }}
      &gt;
        &lt;Show
          when={isExpanded()}
          fallback={&lt;img src=&quot;/chevron-down.svg&quot; width=&quot;10px&quot; height=&quot;10px&quot; alt=&quot;Collapse&quot; /&gt;}
        &gt;
          &lt;img src=&quot;/chevron-up.svg&quot; width=&quot;10px&quot; height=&quot;10px&quot; alt=&quot;Expand&quot; /&gt;
        &lt;/Show&gt;
      &lt;/button&gt;
      &lt;div
        style={{
          display: isExpanded() ? &quot;block&quot; : &quot;none&quot;
        }}
      &gt;
        &lt;p class=&quot;sidebar-note-excerpt&quot; innerHTML={props.note.body || `&lt;i&gt;No content&lt;/i&gt;`} /&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
}
">
<input type="hidden" name="project[files][src/lib/api.ts]" value="import { action, query, redirect } from &quot;@solidjs/router&quot;;
import { format, isToday } from &quot;date-fns&quot;;
import { marked } from &quot;marked&quot;;
import { storage } from &quot;./db&quot;;
import type { Note } from &quot;./types&quot;;

export const getNotes = query(async (searchText: string) =&gt; {
  &quot;use server&quot;;
  return (((await storage.getItem(&quot;notes:data&quot;)) as Note[]) || [])
    .filter(note =&gt; !searchText || note.title.toLowerCase().includes(searchText.toLowerCase()))
    .map(note =&gt; {
      const updatedAt = new Date(note.updatedAt);
      return {
        ...note,
        updatedAt: isToday(updatedAt) ? format(updatedAt, &quot;h:mm bb&quot;) : format(updatedAt, &quot;M/d/yy&quot;)
      };
    });
}, &quot;notes&quot;);

export const getNote = query(async (id: number) =&gt; {
  &quot;use server&quot;;
  return (((await storage.getItem(&quot;notes:data&quot;)) as Note[]) || []).find(note =&gt; note.id === id);
}, &quot;note&quot;);

export const getNotePreview = query(async (id: number) =&gt; {
  &quot;use server&quot;;
  const note = (((await storage.getItem(&quot;notes:data&quot;)) as Note[]) || []).find(
    note =&gt; note.id === id
  );
  if (!note) return;
  note.body = marked(note.body);
  note.updatedAt = format(new Date(note.updatedAt), &quot;d MMM yyyy &#39;at&#39; h:mm bb&quot;);
  return note;
}, &quot;note-preview&quot;);

export const saveNote = action(async (id: number | undefined, formData: FormData) =&gt; {
  &quot;use server&quot;;
  const title = formData.get(&quot;title&quot;) as string;
  const body = formData.get(&quot;body&quot;) as string;
  let [{ value: notes }, { value: index }] = (await storage.getItems([
    &quot;notes:data&quot;,
    &quot;notes:counter&quot;
  ])) as [{ key: string; value: Note[] }, { key: string; value: number }];
  // default value for first write
  notes = notes || [];
  index = index || 0;

  if (id == undefined) {
    await Promise.all([
      storage.setItem(&quot;notes:data&quot;, [
        ...notes,
        { id: index, title, body, updatedAt: new Date().toISOString() }
      ]),
      storage.setItem(&quot;notes:counter&quot;, index + 1)
    ]);
    return redirect(`/notes/${index}`);
  }
  await storage.setItem(
    &quot;notes:data&quot;,
    notes.map(note =&gt; {
      if (note.id !== id) return note;
      return { id, title, body, updatedAt: new Date().toISOString() };
    })
  );
  return redirect(`/notes/${id}`);
});

export const deleteNote = action(async (id: number) =&gt; {
  &quot;use server&quot;;
  const notes = (await storage.getItem(&quot;notes:data&quot;)) as Note[];
  await storage.setItem(
    &quot;notes:data&quot;,
    notes.filter(note =&gt; note.id !== id)
  );
});
">
<input type="hidden" name="project[files][src/lib/db.ts]" value="import { createStorage } from &quot;unstorage&quot;;
import fsLiteDriver from &quot;unstorage/drivers/fs-lite&quot;;

// this uses file system driver for unstorage that works only on node.js
// swap with the key value of your choice in your deployed environment
export const storage = createStorage({
  driver: fsLiteDriver({
    base: &quot;./.data&quot;
  })
});">
<input type="hidden" name="project[files][src/lib/types.ts]" value="export type Note = {
  id: number;
  title: string;
  body: string;
  updatedAt: string;
};">
<input type="hidden" name="project[files][src/routes/(home).tsx]" value="export default function HomePage() {
  return (
    &lt;div class=&quot;note--empty-state&quot;&gt;
      &lt;span class=&quot;note-text--empty-state&quot;&gt;Click a note on the left to view something! 🥺&lt;/span&gt;
    &lt;/div&gt;
  );
}">
<input type="hidden" name="project[files][src/routes/%5B...404%5D.tsx]" value="import { Navigate } from &quot;@solidjs/router&quot;;

export default function NotFound() {
  return &lt;Navigate href=&quot;/&quot; /&gt;;
}
">
<input type="hidden" name="project[files][src/routes/new.tsx]" value="import NoteEditor from &quot;~/components/NoteEditor&quot;;

export default function NewPage() {
  return &lt;NoteEditor initialTitle=&quot;&quot; initialBody=&quot;&quot; /&gt;;
}
">
<input type="hidden" name="project[files][src/routes/notes/%5Bid%5D/(preview).tsx]" value="import { RouteDefinition, RouteSectionProps, createAsync } from &quot;@solidjs/router&quot;;
import { Show } from &quot;solid-js&quot;;
import EditButton from &quot;~/components/EditButton&quot;;
import { getNotePreview } from &quot;~/lib/api&quot;;

export const route = {
  preload({ params }) {
    getNotePreview(+params.id);
  }
} satisfies RouteDefinition;

export default function NotePage({ params }: RouteSectionProps) {
  const note = createAsync(() =&gt; getNotePreview(+params.id));
  return (
    &lt;Show when={note()} keyed&gt;
      {note =&gt; (
        &lt;div class=&quot;note&quot;&gt;
          &lt;div class=&quot;note-header&quot;&gt;
            &lt;h1 class=&quot;note-title&quot;&gt;{note.title}&lt;/h1&gt;
            &lt;div class=&quot;note-menu&quot; role=&quot;menubar&quot;&gt;
              &lt;small class=&quot;note-updated-at&quot; role=&quot;status&quot;&gt;
                Last updated on {note.updatedAt}
              &lt;/small&gt;
              &lt;EditButton noteId={note.id}&gt;Edit&lt;/EditButton&gt;
            &lt;/div&gt;
          &lt;/div&gt;
          &lt;div class=&quot;note-preview&quot;&gt;
            &lt;div class=&quot;text-with-markdown&quot; innerHTML={note.body} /&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      )}
    &lt;/Show&gt;
  );
}
">
<input type="hidden" name="project[files][src/routes/notes/%5Bid%5D/edit.tsx]" value="import { RouteDefinition, RouteSectionProps, createAsync } from &quot;@solidjs/router&quot;;
import { Show } from &quot;solid-js&quot;;
import NoteEditor from &quot;~/components/NoteEditor&quot;;
import { getNote } from &quot;~/lib/api&quot;;

export const route = {
  preload({ params }) {
    getNote(+params.id);
  }
} satisfies RouteDefinition;

export default function EditNote({ params }: RouteSectionProps) {
  const note = createAsync(() =&gt; getNote(+params.id));
  return (
    &lt;Show when={note()}&gt;
      &lt;NoteEditor noteId={+params.id} initialTitle={note()!.title} initialBody={note()!.body} /&gt;
    &lt;/Show&gt;
  );
}
">
<input type="hidden" name="project[description]" value="generated by https://pkg.pr.new">
<input type="hidden" name="project[template]" value="node">
<input type="hidden" name="project[title]" value="example-notes">
</form>
<script>document.getElementById("mainForm").submit();</script>

</body></html>