input, textarea { box-sizing: border-box; max-width: 100%; overflow-x: hidden; } input { text-overflow: ellipsis; white-space: nowrap; } textarea { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; } /* * Theme previews. An element marked data-theme-preview="light|dark" (with * data-tint-preview naming a tint) takes the palette of that appearance and * tint whatever the window wears, and foundations.css recomputes every role * on it, so Settings can draw both appearances of a tint or code theme from * these blocks instead of copying their values. */ :root, [data-theme-preview] { /* Font roles. A build that embeds the Timeless family puts its faces first (scripts/private-fonts.ts); every other build uses these stacks. PingFang SC sets Chinese in both. Code stays on --editor-font. */ --ui-font-fallback: "Inter Variable", Inter, "PingFang SC", "Avenir Next", "Segoe UI", sans-serif; --ui-font: var(--ui-font-fallback); /* Long-form prose: the visual Markdown surface and a paper's title. */ --reading-font: var(--ui-font-fallback); /* The serif voice: Display and Title (foundations.css). Chinese falls through to Songti SC, the macOS system serif, so a title keeps its serif in either language instead of dropping to a heavy sans. */ --display-font-fallback: "Instrument Serif", "Songti SC", "Noto Serif SC", "Source Han Serif SC", Georgia, serif; --display-font: var(--display-font-fallback); --editor-font: "Ioskeley Mono", Menlo, "SF Mono", ui-monospace, monospace; --editor-font-size: var(--type-typeset-size); /* Shared by source CodeMirror and the visual Markdown fixed caret. */ --editor-caret-width: 1.4px; font-family: var(--ui-font); font-weight: var(--weight-regular); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: var(--text); background: var(--window); font-synthesis: none; text-rendering: optimizeLegibility; --sidebar: var(--chrome-surface); --line: rgba(28, 28, 31, 0.09); --line-strong: rgba(28, 28, 31, 0.14); /* Two inks: primary and secondary. Secondary clears 5.5:1 on the chrome, the faintest surface it sits on (foundations.css aliases the old tertiary and chrome text roles to it). */ --text: #242426; --muted: #5f5f64; --accent-graphite: #303033; --accent: var(--accent-graphite); /* Graphite's soft accent: a quiet neutral wash. */ --neutral-soft: rgba(48, 48, 51, 0.08); /* The editor's current line: half that wash, so it marks the caret's line without banding the page. */ --editor-line: rgba(48, 48, 51, 0.045); --accent-soft: var(--neutral-soft); --accent-contrast: #ffffff; /* The keyboard focus ring, and where a dragged tab or panel lands: weft blue, the mark's own thread, so focus never reads as the grey of a selected row (5.5:1 on the sheet, 5:1 on the chrome). An accent preset swaps in the accent. */ --focus: #3b5bd6; --danger: #bc413e; --success: #2c785c; --warning: #8d6400; --info: #6488c5; --brand-weft: #4568f6; --brand-warp: #25b4bb; --brand-glint: rgba(255, 255, 255, 0.85); /* File glyphs, one hue per kind; each clears 3:1 on the sheet, the lift and a selected row. Folders are manila. */ --glyph-tex: #3b5bd6; --glyph-style: #7a52c4; --glyph-bib: #b06a00; --glyph-markdown: #4d6a8a; --glyph-pdf: #c4473c; --glyph-image: #2e8a55; --glyph-board: #13878a; --glyph-sheet: #3a7f2e; --glyph-slides: #c2571c; --glyph-code: #a85a12; --glyph-config: #6a6a70; --glyph-folder: #8a6a3e; --glyph-tint: 16%; /* Local annotations: the highlighter's amber, a step deeper than the .bib glyph so a pin's white figure clears 4.5:1, and the figure's ink on every annotation pin. */ --annotation: #9a5c00; --annotation-contrast: #ffffff; /* The elevation ladder's shadows (foundations.css): one stack per level, the same geometry in both themes and deeper in dark, where a faint shadow disappears into the ground. The ring is the hairline every floating surface carries instead of a border. */ --shadow-ring: rgba(0, 0, 0, 0.05); --shadow-raised: 0 1px 2px rgba(0, 0, 0, 0.06), 0 1px 4px rgba(0, 0, 0, 0.04); --shadow-popover: 0 17.5px 23.4px rgba(0, 0, 0, 0.04), 0 9.4px 12.5px rgba(0, 0, 0, 0.03), 0 5.25px 7px rgba(0, 0, 0, 0.02), 0 2.8px 3.7px -2px rgba(0, 0, 0, 0.01), 0 1.2px 1.5px rgba(0, 0, 0, 0.01); --shadow-floating: 0 25px 50px rgba(0, 0, 0, 0.05), 0 12px 24px rgba(0, 0, 0, 0.04), 0 6px 12px rgba(0, 0, 0, 0.03), 0 3px 6px rgba(0, 0, 0, 0.02), 0 1.5px 3px rgba(0, 0, 0, 0.02); --shadow-dialog: 0 40px 80px rgba(0, 0, 0, 0.06), 0 20px 40px rgba(0, 0, 0, 0.05), 0 10px 20px rgba(0, 0, 0, 0.04), 0 5px 10px rgba(0, 0, 0, 0.03), 0 2px 4px rgba(0, 0, 0, 0.02); /* A compiled page on the PDF ground: paper on a desk, not interface. */ --shadow-pdf-page: 0 8px 24px rgba(22, 22, 24, 0.08); /* Behind a dialog: enough to set it off, light enough that the writer still sees where they were. */ --dialog-scrim: rgba(10, 10, 12, 0.28); --pdf-bg: #efeff0; /* "Weft and warp", Lattice's own code theme (settings/code-themes.ts names the others): the source editor is colored by the mark's two threads. Commands take the weft's blue, environment names and math the warp's teal, and arguments and prose stay in ink, so one blue and one teal carry the structure and nothing competes with the writing. Numbers, operators and citations are the warm voice. Each thread keeps the mark's hue at a text lightness, and every token reads at 4.5:1 or more on the editor, its active line and a focused selection, under every tint. The selection strength is the most the dimmest tokens (comment, bracket) allow. */ --selection-mix: 16%; --selection-mix-focused: 20%; --lattice-syntax-keyword: #3349c4; --lattice-syntax-operator: #7d5100; --lattice-syntax-function: #4553ad; --lattice-syntax-type: #006a6e; --lattice-syntax-variable: #006a6e; --lattice-syntax-variable-special: #7a3fa8; --lattice-syntax-property: #3349c4; --lattice-syntax-attribute: #7a5a08; --lattice-syntax-string: #45454b; --lattice-syntax-comment: #626268; --lattice-syntax-comment-doc: #755026; --lattice-syntax-number: #7d5100; --lattice-syntax-constant: #8d472f; --lattice-syntax-bracket: #626268; --lattice-syntax-citation: #8d472f; --lattice-syntax-reference: #7a3fa8; } /* * The surfaces a tint replaces, at Graphite, the default. Graphite is also a * swatch in Settings, so this applies wherever data-tint names it, as every * tint below does. --tint-mark is only the swatch's identifying hue. * * Graphite has two neutrals and a lift: the ground (the chrome), one sheet * that the panels, the editor and the fields share, and the lift that menus, * popovers, toasts and dialogs stand on. */ :root, [data-tint="graphite"], [data-theme-preview="light"][data-tint-preview="graphite"] { --bg: #f7f7f6; --panel: #fafafa; --panel-strong: #ffffff; --chrome-surface: #efeff0; --side-surface: #fafafa; --editor-bg: #fafafa; --editor-gutter: #fafafa; --tint-mark: #a4a4a6; } :root[data-theme="dark"], [data-theme-preview="dark"] { --line: rgba(255, 255, 255, 0.075); --line-strong: rgba(255, 255, 255, 0.12); --text: #e9e9e7; --muted: #a0a0a7; --accent-graphite: #e7e7e4; --accent: var(--accent-graphite); --neutral-soft: rgba(255, 255, 255, 0.1); --editor-line: rgba(255, 255, 255, 0.05); --accent-soft: var(--neutral-soft); --accent-contrast: #171718; --danger: #ee7772; --success: #66bd99; --warning: #d7a62b; --info: #8fabd8; --focus: #7f97ff; --brand-weft: #7f97ff; --brand-warp: #4fd2c6; --brand-glint: rgba(255, 255, 255, 0.7); --glyph-tex: #8fa5ff; --glyph-style: #bba3f2; --glyph-bib: #f2b65e; --glyph-markdown: #a7bad3; --glyph-pdf: #f39087; --glyph-image: #72cf98; --glyph-board: #62d1cd; --glyph-sheet: #93d07f; --glyph-slides: #f4a06a; --glyph-code: #eaa565; --glyph-config: #9d9da5; --glyph-folder: #d9bc8c; --glyph-tint: 20%; --annotation: #f2b65e; --annotation-contrast: #1a1a1c; /* A floating surface's edge is a quiet hairline; the lift (below) already sets it off the sheet. */ --shadow-ring: rgba(255, 255, 255, 0.1); --shadow-raised: 0 1px 2px rgba(0, 0, 0, 0.24), 0 1px 4px rgba(0, 0, 0, 0.16); --shadow-popover: 0 17.5px 23.4px rgba(0, 0, 0, 0.16), 0 9.4px 12.5px rgba(0, 0, 0, 0.12), 0 5.25px 7px rgba(0, 0, 0, 0.08), 0 2.8px 3.7px -2px rgba(0, 0, 0, 0.04), 0 1.2px 1.5px rgba(0, 0, 0, 0.04); --shadow-floating: 0 25px 50px rgba(0, 0, 0, 0.2), 0 12px 24px rgba(0, 0, 0, 0.16), 0 6px 12px rgba(0, 0, 0, 0.12), 0 3px 6px rgba(0, 0, 0, 0.08), 0 1.5px 3px rgba(0, 0, 0, 0.08); --shadow-dialog: 0 40px 80px rgba(0, 0, 0, 0.24), 0 20px 40px rgba(0, 0, 0, 0.2), 0 10px 20px rgba(0, 0, 0, 0.16), 0 5px 10px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.08); --shadow-pdf-page: 0 10px 28px rgba(0, 0, 0, 0.28); --dialog-scrim: rgba(0, 0, 0, 0.5); --pdf-bg: color-mix(in srgb, var(--bg) 84%, #888 16%); /* As strong as the dimmest token (comment) allows at 4.5:1. */ --selection-mix: 19%; --selection-mix-focused: 24%; --lattice-syntax-keyword: #93a6ff; --lattice-syntax-operator: #e8b25c; --lattice-syntax-function: #aab3ee; --lattice-syntax-type: #5cd0c8; --lattice-syntax-variable: #5cd0c8; --lattice-syntax-variable-special: #d59bf0; --lattice-syntax-property: #93a6ff; --lattice-syntax-attribute: #ffd36d; --lattice-syntax-string: #d2d2d6; --lattice-syntax-comment: #9e9ea5; --lattice-syntax-comment-doc: #c19a70; --lattice-syntax-number: #e8b25c; --lattice-syntax-constant: #dfa27d; --lattice-syntax-bracket: #a4a4ab; --lattice-syntax-citation: #dfa27d; --lattice-syntax-reference: #d59bf0; } :root[data-theme="dark"], :root[data-theme="dark"] [data-tint="graphite"], [data-theme-preview="dark"][data-tint-preview="graphite"] { --bg: #171718; --panel: #1a1a1c; /* Lifts step about 6% above the sheet, so a menu or dialog reads off it without a bright edge. */ --panel-strong: #252528; --chrome-surface: #131315; --side-surface: #1f1f22; /* The editor stands on the tool panels' surface (Git, History, Overleaf), so every panel's tab strip and body read as one sheet. */ --editor-bg: var(--side-surface); --editor-gutter: var(--side-surface); } /* * Theme presets (Settings → Appearance), set on the root by use-appearance.ts. * * A tint moves the neutral surfaces to one hue at the lightness they already * had (in OKLCH), so every syntax token keeps its 4.5:1 on the editor. Chrome * takes the full tint; the editor and panels take 70% of it. Text and lines * stay neutral. Graphite, the default, is the palette above. */ [data-tint="paper"], [data-theme-preview="light"][data-tint-preview="paper"] { --bg: #fbf6ef; --panel: #fefaf5; --panel-strong: #fcf9f4; --chrome-surface: #f3eee7; --side-surface: #fcf9f4; --editor-bg: #fcf9f4; --editor-gutter: #fcf9f4; --tint-mark: #cdb38c; } :root[data-theme="dark"] [data-tint="paper"], :root[data-theme="dark"][data-tint="paper"], [data-theme-preview="dark"][data-tint-preview="paper"] { --bg: #191713; --panel: #1d1b18; --panel-strong: #22201d; --chrome-surface: #171410; --side-surface: #1d1b18; } [data-tint="sage"], [data-theme-preview="light"][data-tint-preview="sage"] { --bg: #f2f9f3; --panel: #f8fdf8; --panel-strong: #f6fbf6; --chrome-surface: #eaf1eb; --side-surface: #f6fbf6; --editor-bg: #f6fbf6; --editor-gutter: #f6fbf6; --tint-mark: #9dc3a3; } :root[data-theme="dark"] [data-tint="sage"], :root[data-theme="dark"][data-tint="sage"], [data-theme-preview="dark"][data-tint-preview="sage"] { --bg: #141915; --panel: #191c1a; --panel-strong: #1e211f; --chrome-surface: #111612; --side-surface: #191c1a; } [data-tint="mist"], [data-theme-preview="light"][data-tint-preview="mist"] { --bg: #f0f8ff; --panel: #f6fcff; --panel-strong: #f4faff; --chrome-surface: #e8f0f8; --side-surface: #f4faff; --editor-bg: #f4faff; --editor-gutter: #f4faff; --tint-mark: #98bcdc; } :root[data-theme="dark"] [data-tint="mist"], :root[data-theme="dark"][data-tint="mist"], [data-theme-preview="dark"][data-tint-preview="mist"] { --bg: #12181d; --panel: #181c1f; --panel-strong: #1d2125; --chrome-surface: #0f151a; --side-surface: #181c1f; } [data-tint="dusk"], [data-theme-preview="light"][data-tint-preview="dusk"] { --bg: #f8f5ff; --panel: #fcfaff; --panel-strong: #faf8ff; --chrome-surface: #f0edf7; --side-surface: #faf8ff; --editor-bg: #faf8ff; --editor-gutter: #faf8ff; --tint-mark: #bdafd9; } :root[data-theme="dark"] [data-tint="dusk"], :root[data-theme="dark"][data-tint="dusk"], [data-theme-preview="dark"][data-tint-preview="dusk"] { --bg: #18161d; --panel: #1c1a1f; --panel-strong: #211f24; --chrome-surface: #15131a; --side-surface: #1c1a1f; } /* * Accent presets. Each reads at 4.6:1 or more on every surface of every tint * in its theme, because the accent also colors text (outline links, roles, * active toolbar icons); its label color clears 4.5:1 on it. A custom accent * is fitted to the same floor in theme-customization.ts and set inline. * Graphite, the default, keeps the neutral accent and the weft-blue focus ring. */ [data-accent="graphite"] { --accent: var(--accent-graphite); } [data-accent="blue"] { --accent: #096acb; } :root[data-theme="dark"] [data-accent="blue"], :root[data-theme="dark"][data-accent="blue"] { --accent: #4d8fe0; } [data-accent="purple"] { --accent: #884fbe; } :root[data-theme="dark"] [data-accent="purple"], :root[data-theme="dark"][data-accent="purple"] { --accent: #a679d5; } [data-accent="pink"] { --accent: #b83b76; } :root[data-theme="dark"] [data-accent="pink"], :root[data-theme="dark"][data-accent="pink"] { --accent: #d56b97; } [data-accent="orange"] { --accent: #b04d00; } :root[data-theme="dark"] [data-accent="orange"], :root[data-theme="dark"][data-accent="orange"] { --accent: #d37438; } [data-accent="green"] { --accent: #007c34; } :root[data-theme="dark"] [data-accent="green"], :root[data-theme="dark"][data-accent="green"] { --accent: #3da05a; } [data-accent="teal"] { --accent: #007777; } :root[data-theme="dark"] [data-accent="teal"], :root[data-theme="dark"][data-accent="teal"] { --accent: #139d9e; } [data-accent]:not([data-accent="graphite"]) { --accent-soft: color-mix(in srgb, var(--accent) 10%, transparent); --focus: var(--accent); } :root[data-theme="dark"] [data-accent]:not([data-accent="graphite"]), :root[data-theme="dark"][data-accent]:not([data-accent="graphite"]) { --accent-soft: color-mix(in srgb, var(--accent) 14%, transparent); } /* * Window material. Opaque by default; `data-glass` is set only when the * window really has macOS vibrancy behind it (use-appearance.ts asks the * native side, which also answers for Reduce transparency), so a browser tab * never shows a see-through page. The window itself turns clear and the * titlebar and gutters take --glass-shell of the chrome color over the * material, as Synara's shell does; Project and Papers sit on top as a * --glass-panel sheet, and a page that fills the window (the welcome screen) * at --glass-page. On that sheet a frosted panel's header and body take one * more coat together, a white veil of --glass-lift. The editors, PDFs, the * agent, the tool panels and every dialog stay opaque. */ :root, [data-theme-preview] { --window: var(--bg); --glass-shell: 100%; --glass-panel: 100%; --glass-page: 100%; --glass-lift: 0%; } :root[data-glass] { --window: transparent; } :root[data-glass="subtle"] { --glass-shell: 40%; --glass-panel: 45%; --glass-page: 72%; --glass-lift: 34%; } :root[data-glass="strong"] { --glass-shell: 0%; --glass-panel: 50%; --glass-page: 52%; --glass-lift: 30%; } :root[data-theme="dark"][data-glass="subtle"] { --glass-shell: 45%; --glass-panel: 45%; --glass-page: 74%; --glass-lift: 5%; } :root[data-theme="dark"][data-glass="strong"] { --glass-shell: 0%; --glass-panel: 60%; --glass-page: 62%; --glass-lift: 5%; } /* * The titlebar is the shell under a veil of white, so it reads as a sheet * lifted a step off the gutters beneath it, toward the panels, and a hairline * closes its lower edge. A veil rather than a fixed color, so it keeps the * tint's hue and frosts the window material the same way it lightens the * opaque chrome. Dark needs far less white for the same step. */ :root { --titlebar-veil: 45%; } :root[data-theme="dark"] { --titlebar-veil: 3.5%; } :root[data-glass] { --titlebar-veil: 38%; } :root[data-theme="dark"][data-glass] { --titlebar-veil: 4.5%; } @media (pointer: fine) { /* * The two scrollbar styling systems cannot be declared together. WebKit and * Blink ignore every `::-webkit-scrollbar-*` rule on a scroller that also * sets `scrollbar-width` or `scrollbar-color`, so declaring both here meant * the standard properties won and the geometry below — a 10px track inset by * 5px + 1px borders, i.e. the same 4px thumb the overlay ScrollArea draws — * never rendered anywhere in the app. Native scrollers fell back to the * platform's thicker "thin" bar, which is why they never matched the PDF * viewer's. Keep the standard properties for engines that have no legacy * pseudo-elements; the query is false in WebKit either way it answers. */ @supports not selector(::-webkit-scrollbar) { * { scrollbar-width: thin; scrollbar-color: transparent transparent; } *:hover, *:focus-within { scrollbar-color: color-mix(in srgb, var(--text-primary) 12%, transparent) transparent; } } *::-webkit-scrollbar { width: 10px; height: 10px; } *::-webkit-scrollbar-track, *::-webkit-scrollbar-corner { background: transparent; } *::-webkit-scrollbar-thumb { border: 3px solid transparent; border-radius: var(--radius-pill); background: transparent; background-clip: content-box; } *::-webkit-scrollbar-thumb:vertical { border-right-width: 5px; border-left-width: 1px; } *::-webkit-scrollbar-thumb:horizontal { border-top-width: 1px; border-bottom-width: 5px; } *:hover::-webkit-scrollbar-thumb, *:focus-within::-webkit-scrollbar-thumb { background-color: color-mix(in srgb, var(--text-primary) 12%, transparent); } *::-webkit-scrollbar-thumb:hover { background-color: color-mix(in srgb, var(--text-primary) 12%, transparent); } *::-webkit-scrollbar-thumb:vertical:hover { border-right-width: 4px; border-left-width: 0; } *::-webkit-scrollbar-thumb:horizontal:hover { border-top-width: 0; border-bottom-width: 4px; } *::-webkit-scrollbar-thumb:active { background-color: color-mix(in srgb, var(--text-primary) 16%, transparent); } }