-
+
Can’t parse: {{ error }}
@@ -32,15 +79,20 @@ function onInput(e: Event) {
height: 100%;
min-height: 0;
}
-.editor-area {
+.code {
+ position: relative;
flex: 1;
- width: 100%;
- resize: none;
- border: none;
- outline: none;
+ min-height: 0;
+}
+/* Backdrop (highlighted) and textarea (input) share identical box metrics so the
+ transparent input text sits exactly over its colored Shiki copy. */
+.backdrop,
+.input {
+ position: absolute;
+ inset: 0;
+ margin: 0;
+ border: 0;
padding: 0.9rem 1rem;
- background: var(--color-base-100);
- color: var(--color-base-content);
font-family: inherit; /* Fira Code, from the global theme */
font-size: 0.8rem;
line-height: 1.6;
@@ -48,9 +100,36 @@ function onInput(e: Event) {
white-space: pre;
overflow: auto;
}
+.backdrop {
+ z-index: 0;
+ pointer-events: none;
+ overflow: hidden; /* scroll is driven by the textarea via syncScroll */
+ background: var(--color-base-100);
+ color: var(--color-base-content);
+}
+/* Neutralise Shiki's own
chrome — the .backdrop provides padding/metrics. */
+.backdrop :deep(pre.shiki) {
+ margin: 0;
+ padding: 0;
+ background: transparent !important;
+ white-space: pre;
+}
+.backdrop :deep(pre.shiki),
+.backdrop :deep(pre.shiki code) {
+ font: inherit;
+}
+.input {
+ z-index: 1;
+ resize: none;
+ outline: none;
+ background: transparent;
+ color: transparent;
+ caret-color: var(--color-base-content);
+}
+.input::selection {
+ background: color-mix(in oklch, var(--color-primary) 28%, transparent);
+}
.editor-error {
- position: sticky;
- bottom: 0;
padding: 0.6rem 1rem;
font-size: 0.74rem;
background: var(--color-error);