diff --git a/AGENTS.md b/AGENTS.md index be53d16..6ad7fe3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -100,3 +100,4 @@ Assume environment is set up. - Pressidian enrolls previously unmanaged private Knowledge rows when they have any administrator-selected Knowledge Type (default `note` or `todo`), skips Gutenberg block-shaped content, and keeps already-enrolled rows synced if their types later change. It uses the existing immutable WordPress slug as record identity, calls the Markdown representation kind `markdown`, hides derived `artifact`/`note`/`obsidian` terms from Obsidian tags, exposes `todo` and other semantic terms as tags, preserves TODO operational meta, and treats WordPress trash as a sync tombstone rather than a hard delete. - The default Knowledge-only wp-env intentionally omits the standalone Abilities API plugin. PHPUnit bootstrap must treat that fixture as optional and stay silent when it is absent; writing the expected absence to STDERR breaks tests marked `@runInSeparateProcess` before they can skip. - `pull_request_target` evaluates the workflow definition from the base branch but may execute local composite actions from the checked-out PR merge ref. During CI migrations, keep changed composite actions backward-compatible with the base workflow's inputs until the workflow change has merged; the split build action therefore falls back to the legacy monolith preview ZIP when no package slug is supplied. +- The public landing page is the static GitHub Pages site in `docs/` (custom domain `personalos.net`). Keep it focused on the six standalone Knowledge-backed packages, distinguish four app destinations from two background sync integrations, and verify release assets before advertising downloads; the merged Stuff package initially exists only in source. Use synthetic demo records for public app screenshots and attach a full-page design capture to landing-page PRs. diff --git a/docs/INSTALL.md b/docs/INSTALL.md index c18e81a..ee8a96b 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -1,8 +1,71 @@ -# Get PersonalOS +# Install PersonalOS plugins -## I have a WordPress site +PersonalOS is a set of six independent plugins built on WordPress Knowledge. Install only the modules you want; no PersonalOS base plugin or sibling plugin is required. -## Getting a WordPress site +## Requirements -## Get a WordPress on your laptop +- WordPress 7.0 or later **with a Knowledge runtime** that registers `wp_knowledge`, hierarchical `wp_knowledge_type`, and the core `/wp/v2/knowledge` REST collection. The WordPress version number alone does not guarantee that Knowledge is available. Check your runtime before installing. +- PHP 7.4 or later for Notes, TODO, Stuff, and AI Chat; PHP 7.2.24 or later for the Readwise and Evernote integrations. +- Pretty permalinks for the private app routes. In WordPress, open **Settings → Permalinks** and choose a structure such as **Post name**. +- A WordPress account with permission to edit posts to use the apps. +AI Chat additionally needs WordPress AI Client and a configured provider through Connectors to generate replies. Readwise and Evernote imports need your credentials for those services. Core Knowledge access does not require an AI provider. + +## Choose your plugins + +Download individual ZIPs from [GitHub Releases](https://github.com/artpi/PersonalOS/releases). In WordPress, use **Plugins → Add New Plugin → Upload Plugin**, upload a ZIP, and activate it. + +| Plugin | Where to open it | What it adds | +| --- | --- | --- | +| Personal Notes | `/notes/` | Note library, Knowledge Type organization, and editor integration | +| Personal TODO | `/todo/` | Tasks, scheduling, recurrence, dependencies, history, and ICS feeds | +| Personal Stuff | `/stuff/` | Inventory with photos, places, tags, search, and print/PDF | +| Personal AI Chat | `/ai-chat/` | Conversations saved in Knowledge, generation through AI Client | +| Personal Readwise Sync | Settings → Personal Readwise Sync | Import Readwise highlights and articles | +| Personal Evernote Sync | Settings → Personal Evernote Sync | One-way import from selected Evernote notebooks | + +As of September 6, 2026, release `0.3.0` contains five plugin ZIPs. Personal Stuff is merged into `main` and can be built from source; it is awaiting its first release ZIP. Check the release asset list before downloading. + +Open Readwise or Evernote settings to add your per-user token and configure the import scope. The integrations run in the background; apps such as Personal Notes can read their imported Knowledge records. + +## Try the local development site + +The repository's `wp-env` configuration mounts all six packages. It uses pinned Gutenberg 23.7.0 and enables its Knowledge experiment as a **development fixture**. That fixture is not a bundled release dependency or a promise of production support for the experiment. + +With Node.js, Composer, and Docker available: + +```bash +git clone https://github.com/artpi/PersonalOS.git +cd PersonalOS +npm ci +composer install +npm run build +npm run wp-env -- start +``` + +Open [localhost:8901](http://localhost:8901), sign in using wp-env's default development credentials (`admin` / `password`), and configure pretty permalinks. Then open `/notes/`, `/todo/`, `/stuff/`, or `/ai-chat/`. Use these default credentials only for local development. + +If your WordPress environment does not provide Knowledge, the apps need a compatible runtime before they can work. The repository fixture is a way to evaluate the plugins locally. + +## Build installable ZIPs + +From the repository root, after installing dependencies and building assets: + +```bash +# Build all six standalone plugins. +npm run package:plugins +npm run verify:split-packages + +# Or build just Personal Stuff. +npm run package:plugin -- --package=personal-stuff +``` + +The packaging command reports the output paths. Install the generated ZIP, rather than copying a package source directory: release ZIPs contain their own shared helpers and required bundled runtimes. + +## Your data and connections + +The apps store their durable records in WordPress Knowledge. User-created records are private by default and use WordPress permissions. Deactivation or uninstall leaves records in place. This does not guarantee that every Knowledge consumer displays every type of record: each app chooses its own relevant types. + +Stuff photos are WordPress Media attachments. Their URLs remain publicly accessible to someone who knows the URL, even when the inventory record is private. Knowledge Type terms retain the visibility provided by your Knowledge runtime. + +Readwise and Evernote contact the services you configure. AI generation sends prompts to your configured provider. See each [package readme](https://github.com/artpi/PersonalOS/tree/main/packages) for the exact privacy and retention behavior. diff --git a/docs/assets/knowledge-notes.png b/docs/assets/knowledge-notes.png new file mode 100644 index 0000000..966e977 Binary files /dev/null and b/docs/assets/knowledge-notes.png differ diff --git a/docs/assets/knowledge-stuff.png b/docs/assets/knowledge-stuff.png new file mode 100644 index 0000000..93aa0c8 Binary files /dev/null and b/docs/assets/knowledge-stuff.png differ diff --git a/docs/assets/knowledge-todo.png b/docs/assets/knowledge-todo.png new file mode 100644 index 0000000..509c870 Binary files /dev/null and b/docs/assets/knowledge-todo.png differ diff --git a/docs/assets/mark.svg b/docs/assets/mark.svg new file mode 100644 index 0000000..ae9c721 --- /dev/null +++ b/docs/assets/mark.svg @@ -0,0 +1 @@ + diff --git a/docs/design/README.md b/docs/design/README.md new file mode 100644 index 0000000..f258b52 --- /dev/null +++ b/docs/design/README.md @@ -0,0 +1,30 @@ +# Knowledge landing page design + +The public site is served directly from `docs/` by GitHub Pages at `personalos.net`. It has local CSS, a small script for screenshot tabs, and no runtime CDN, font service, or build dependency. + +Preview it from the repository root: + +```bash +python3 -m http.server 4173 --bind 127.0.0.1 --directory docs +``` + +Open `http://127.0.0.1:4173`. + +## Design captures + +- [Full-height desktop, 1440px wide](knowledge-landing-desktop.png) +- [Full-height mobile, 390px wide](knowledge-landing-mobile.png) + +The three app screenshots under `docs/assets/knowledge-*.png` are unmodified browser captures of the running local wp-env site at 1440×900. The site had all six split plugins active, with its pinned Gutenberg Knowledge fixture. An isolated author account named Demo owns eight synthetic notes, seven synthetic tasks, and four synthetic inventory items. The Stuff screenshot is filtered to the synthetic Field kit tag. No personal notes, photos, or credentials are included. The hero map and record panel are explanatory illustrations, not app screenshots. + +## Verification — September 6, 2026 + +- CSS and JavaScript pass the repository's WordPress linters; `node --check docs/site.js` and `git diff --check` pass. +- Chromium browser checks at 320, 375, 390, 768, 820, 1024, and 1440px: no horizontal overflow, page errors, or failed local asset responses. +- All three screenshot tabs work with clicks and keyboard navigation, including arrow keys, Home, and End. Selected state, focus, panel visibility, URL decoration, and captions update together. +- Axe's WCAG 2 A/AA and WCAG 2.1 AA checks report zero violations at the checked 1440px desktop viewport. This is an automated scan, not a comprehensive accessibility certification. +- All internal anchors and linked repository paths resolve. The default screenshot and all six modules remain available without JavaScript. +- Desktop and mobile captures were visually reviewed. Screenshots were decoded before full-page capture; the default tab is Notes. Reduced-motion preference is respected. +- The latest published release was inspected: `0.3.0` has the five pre-Stuff ZIPs. The landing page links to the releases list and identifies Stuff as source-available while its first ZIP is pending. + +This change is static site content, styles, screenshots, and installation documentation. Plugin code and wp-env configuration are unchanged; backend suites were not rerun for this page redesign. diff --git a/docs/design/knowledge-landing-desktop.png b/docs/design/knowledge-landing-desktop.png new file mode 100644 index 0000000..05b7bf7 Binary files /dev/null and b/docs/design/knowledge-landing-desktop.png differ diff --git a/docs/design/knowledge-landing-mobile.png b/docs/design/knowledge-landing-mobile.png new file mode 100644 index 0000000..050258a Binary files /dev/null and b/docs/design/knowledge-landing-mobile.png differ diff --git a/docs/index.html b/docs/index.html index 5bfcbf6..dd011fd 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,547 +1,609 @@ - + - - - - PersonalOS - Your Personal Operating System - - - - - - - - - - - - - - + + + + + + + + + + PersonalOS — Your life, connected by Knowledge + + + + + + + +
+
+
+

+ A personal operating system for + WordPress +

+

+ Your life.
Your data.
All connected. +

+

+ A home for your notes, tasks, and everyday things. Independent apps + that speak the same language: WordPress Knowledge. +

+ +

+ Self-hosted. Open source. Yours to build on. +

+
+ +
+
+ Built on WordPress Six independent plugins One shared data model GPL-2.0-or-later +
- -
-
-
-
-

- Your Personal Operating System -

-

- PersonalOS is your all-in-one personal management system, designed to keep your personal data in your control, but accessible for AI agents. -

- - Get Started - -
-
-
-
-

[Mockup Placeholder: Sleek app interface showing todos and notes]

-
-
-
-
-
+
+
+
+

01 / THE CONNECTIVE TISSUE

+

Different apps.
Common ground.

+

+ A highlight you saved. A task you need to finish. The box with + your camera gear. They belong to your life. Their data should live + together, too. +

+

+ PersonalOS stores them as native WordPress Knowledge records. Each + app adds its own view and behavior; compatible plugins and tools + can work with the same underlying content. +

+ Explore the shared foundation + +
+
+
+ ANATOMY OF A KNOWLEDGE + RECORD +
+
+ +
+ PERSONAL STUFF +

The weekend camera

+
+ Private +
+
+
+
Content
+
Notes, photos & native blocks
+
+
+
Knowledge Type
+
+ artifactstuff-itemtravel +
+
+
+
Storage
+
wp_knowledge
+
+
+
Access
+
WordPress permissions + REST API
+
+
+
+ GET/wp-json/wp/v2/knowledge +
+

+ An illustrative record. A native format.
Ready for another + Knowledge-aware tool. +

+
+
+
+ 01 +

Shared meaning

+

+ Knowledge Types describe what a record is and where it belongs. + Apps keep their own focused views. +

+
+
+ 02 +

Native building blocks

+

+ Posts, terms, blocks, media, and REST. Familiar WordPress + primitives make your data useful beyond one interface. +

+
+
+ 03 +

Room for your tools

+

+ Build on the core Knowledge API. TODO also exposes task actions + through the WordPress Abilities API. +

+
+
+
+
- -
+
+
+
+

02 / BUILD YOUR OWN EVERYDAY

+

A small set of tools.
A very personal system.

+
+

+ Start with what you need. Add what you love.
Every module is a + standalone plugin. No other PersonalOS plugin required. +

+
+
+
+
+ APP / 01 +
+

Personal Notes

+

+ A place for unfinished thoughts and useful knowledge. Search, + organize, and bring your notes into the WordPress editor. +

+
    +
  • Shared Knowledge Types & PARA organization
  • +
  • Native block or classic editing
  • +
  • Find and embed notes from the editor sidebar
  • +
+ Explore Notes +
+
+
+ APP / 02 +
+

Personal TODO

+

+ Make space for what matters now. Capture tasks quickly, plan what + comes next, and let the recurring things take care of themselves. +

+
    +
  • Scheduling, recurrence & dependencies
  • +
  • Task history and a personal ICS calendar feed
  • +
  • Task actions through the Abilities API
  • +
+ Explore TODO +
+
+
+ NEW / APP 03 +
+

Personal Stuff

+

+ Remember what you own. And where you put it. A visual inventory + for the gear, boxes, and everyday objects in your life. +

+
    +
  • Photo galleries, places & tags
  • +
  • Search location paths and print to PDF
  • +
  • Native Knowledge, Media & editor APIs
  • +
+ Explore Stuff +
+
+
+ APP / 04 +
+

Personal AI Chat

+

+ A home for conversations with AI. Keep your chat history in + Knowledge and connect generation through WordPress AI Client. +

+
    +
  • Saved conversations as native blocks
  • +
  • Provider setup through WordPress Connectors
  • +
  • Discover registered WordPress abilities
  • +
+ Explore AI Chat + +
+
+
+ SYNC / 05 +
+

Personal Readwise Sync

+

+ Good ideas deserve a second life. Bring your Readwise highlights + and articles into Knowledge, alongside your own notes. +

+
    +
  • Incremental imports with source attribution
  • +
  • Per-user Readwise connection
  • +
  • Optional AI-powered book summaries
  • +
+ Explore Readwise Sync + +
+
+
+ SYNC / 06 +
+

Personal Evernote Sync

+

+ Bring an existing notebook habit home. Import selected Evernote + notebooks into WordPress as private Knowledge records. +

+
    +
  • One-way import from Evernote
  • +
  • Per-user connection and notebook scope
  • +
  • Read imported notes in Knowledge-aware apps
  • +
+ Explore Evernote Sync + +
+
+

+ Four private app destinations. Two + background integrations. One WordPress site. +

+
- -
-

- Your Second Brain, in your digital home -

- - -
- -
-

- - TODOs -

-
- PersonalOS TODOs interface -
-

- An opinionated TODO manager designed to surface what's important right now while giving you the peace of mind that everything is taken care of: -

    -
  • - - Assign TODOS to NOW / LATER / FollowUP -
  • -
  • - - Automatically transition statuses -
  • -
  • - - Set blocking TODOs for bigger projects -
  • -
  • - - Projects, contexts, areas,.. -
  • -
  • - - Offline sync with dedicated WP-TODO mobile app -
  • -
-

- - All TODO features - - -
- - -
-

- - Notes -

-
- PersonalOS Notes interface -
-

- Your notes, now powered with the most extensible editor on the web - WordPress Block Editor. -

    -
  • - - Embedded notes for creating networked ideas -
  • -
  • - - Search for related concepts in sidebar or through autocompleter -
  • -
  • - - Use your favorite blocks from thousands of WordPress plugins -
  • . -
  • - - Built-in synchronization with Readwise, Evernote, ... -
  • -
-

- - All Notes features - - -
-
-
- - +
+
+
+
+

03 / LESS ABSTRACT. MORE EVERYDAY.

+

+ Feels like your own
little corner of the internet. +

+
+

+ Familiar WordPress foundations.
Focused spaces for getting on + with life. +

+
+
+ REAL APPS, DEMO CONTENT +
+
+ +
+ Personal Notes running on WordPress with sample notes, Knowledge Type labels, source information, and native DataViews search. +
+ + +
+
+

+ Your notes, organized with Knowledge Types and the native + WordPress DataViews interface. +

+ LOCAL WORDPRESS DEMO · CLICK TO ENLARGE +
+
+
-
-

- Designed for AI -

-

- Invite AI into your Second Brain so it can read your mind. -

-
-
-

- - Environment for your Agents -

-

- Effortlessly share context with AI to set it up for success the first time. -

    -
  • - - - Get context from your projects, notes, todos and blog -
  • -
  • - - Stop copy-pasting stuff to GPTs -
  • -
  • - - -
  • -
-

-
-
-

- - Integrates with everything -

-

- Give AI superpowers to external services. -

    -
  • - - Sync notes from Readwise and Evernote -
  • -
  • - - Sync your TODOs from iOS Reminders -
  • -
  • - - Command your Second Brain through Slack -
  • -
  • - - Custom GPTs with your personal context -
  • -
-

-
-
-

- - Your AI podcast -

-

- Start your day with a personal podcast from your Second Brain. -

    -
  • - - Personalized daily briefings that you care about -
  • -
  • - - Your Personal Voice Mode now reads your mind -
  • -
  • - - Turn chores into productive time -
  • -
-

-
-
-
+
+

04 / A DIGITAL HOME, ON YOUR TERMS

+
+

Apps come and go.
Your knowledge stays.

+
+

+ These plugins add ways to work with your data. The records live in + WordPress, and remain there when a PersonalOS plugin is + deactivated or uninstalled. +

+

+ User-created records are private by default, with WordPress + controlling access. Sync services and AI providers are connections + you configure. Stuff photos use standard WordPress Media URLs; + private records do not make those files private. +

+ Read the code. Make it your own. + +
+
+
-
-

- Engineered for the long run -

-

- PersonalOS is built on top of WordPress, the most popular self-hosted, and most extensible CMS in the world.
Your data is in your control in a familiar interface. -

-
-
-

- - Platform Independence -

-

- PersonalOS will work just as good in 50 years -

-
    -
  • - - You can host it inside a safe if you want -
  • -
  • - - Google can't shut it down +
    +
    +
    +

    + SMALL TOOLS. AN OPEN FOUNDATION. +

    +

    Make yourself
    at home.

    +

    + Pick a plugin. Connect it to Knowledge.
    Build a system that + feels like you. +

    + +
    +
      +
    1. + 01 +
      +

      Bring your WordPress

      +

      + Target WordPress 7.0+ with a runtime that provides Knowledge. + The repository includes a local development fixture. +

      +
    2. -
    3. - - Data is stored in future-proof formats. +
    4. + 02 +
      +

      Choose your modules

      +

      + Install individual plugin ZIPs. Stuff is available from source + on main while awaiting its first release ZIP. +

      +
    5. -
-
-
-

- - Powerful Integrations -

-

- WordPress has thousands of plugins, and PersonalOS is built to integrate with them seamlessly. -

-
-
-

- - Power of Open Source -

-

- Incentivized to integrate with everything -

-
    -
  • - - No investors = no monetization pressure +
  • + 03 +
    +

    Settle in

    +

    + Open your apps. Add tokens for the sync integrations, or + configure AI Client and a provider for AI Chat. +

    +
  • -
  • - - You want a feature? Implement it yourself! -
  • -
-
-
-
-
- - -
-
-
-

- - Try it yourself -

-

- Launch a fully-functioning WordPress instance with PersonalOS pre-installed, inside your browser. Data will never leave your browser, but AI features will require your own API keys. -

- +
+
+
+ + + diff --git a/docs/site.js b/docs/site.js new file mode 100644 index 0000000..524561d --- /dev/null +++ b/docs/site.js @@ -0,0 +1,40 @@ +const tabs = [ ...document.querySelectorAll( '[role="tab"]' ) ]; +const captions = { + notes: 'Your notes, organized with Knowledge Types and the native WordPress DataViews interface.', + todo: 'A focused task list with the scheduling, recurrence, and Knowledge Types behind your everyday work.', + stuff: 'Your belongings, organized by place and tag. This filtered view contains only synthetic demo items.', +}; + +function selectTab( tab ) { + for ( const item of tabs ) { + const selected = item === tab; + item.setAttribute( 'aria-selected', String( selected ) ); + item.tabIndex = selected ? 0 : -1; + document.getElementById( item.getAttribute( 'aria-controls' ) ).hidden = + ! selected; + } + const app = tab.id.replace( 'tab-', '' ); + document.getElementById( 'preview-path' ).textContent = `/${ app }/`; + document.getElementById( 'preview-caption' ).textContent = captions[ app ]; +} + +for ( const tab of tabs ) { + tab.addEventListener( 'click', () => selectTab( tab ) ); + tab.addEventListener( 'keydown', ( event ) => { + let index = tabs.indexOf( tab ); + if ( event.key === 'ArrowRight' ) { + index = ( index + 1 ) % tabs.length; + } else if ( event.key === 'ArrowLeft' ) { + index = ( index - 1 + tabs.length ) % tabs.length; + } else if ( event.key === 'Home' ) { + index = 0; + } else if ( event.key === 'End' ) { + index = tabs.length - 1; + } else { + return; + } + event.preventDefault(); + selectTab( tabs[ index ] ); + tabs[ index ].focus(); + } ); +} diff --git a/docs/style.css b/docs/style.css new file mode 100644 index 0000000..2fd3719 --- /dev/null +++ b/docs/style.css @@ -0,0 +1,1821 @@ +:root { + --paper: #f6f5ee; + --ink: #233d33; + --muted: #617066; + --line: #dce0d4; + --green: #193e33; + --lime: #d4ed95; + --serif: georgia, "Times New Roman", serif; + --sans: -apple-system, blinkmacsystemfont, "Segoe UI", sans-serif; +} + +* { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + scroll-padding-top: 28px; +} + +body { + margin: 0; + background: var(--paper); + color: var(--ink); + font-family: var(--sans); + -webkit-font-smoothing: antialiased; +} + +a { + color: inherit; + text-decoration: none; +} + +button { + font: inherit; + cursor: pointer; +} + +a, +button { + -webkit-tap-highlight-color: transparent; + touch-action: manipulation; +} + +a:focus-visible, +button:focus-visible, +[tabindex]:focus-visible { + outline: 3px solid #6b873b; + outline-offset: 6px; +} + +a:hover { + text-decoration-thickness: 1px; +} + + +img { + display: block; + max-width: 100%; + height: auto; +} + + +p { + line-height: 1.75; +} + +h1, +h2, +h3, +p { + margin-top: 0; +} + +h1, +h2 { + font-family: var(--serif); + font-weight: 400; + letter-spacing: -2.8px; +} + +h2 { + font-size: clamp(38px, 4vw, 56px); + line-height: 1.1; + margin-bottom: 24px; +} + +h1 em, +h2 em { + font-weight: 400; + color: #687e51; +} + +.wrap { + width: min(1240px, calc(100% - 112px)); + margin-inline: auto; +} + +.eyebrow { + font-family: var(--sans); + font-size: 10px; + font-weight: 650; + line-height: 1.6; + letter-spacing: 1.7px; + margin-bottom: 26px; +} + +.status-dot { + display: inline-block; + width: 6px; + height: 6px; + background: #79994d; + border-radius: 50%; + vertical-align: middle; + margin-right: 7px; +} + +.button { + display: inline-flex; + justify-content: center; + align-items: center; + gap: 28px; + padding: 17px 23px; + border: 1px solid var(--green); + background: var(--green); + color: #fff; + border-radius: 7px; + font-size: 13px; + font-weight: 600; + line-height: 1.4; + transition: + background 160ms, + transform 160ms; +} + +.button:hover { + background: #2b5846; + transform: translateY(-2px); +} + +.button > span, +.text-link > span { + font-size: 19px; + line-height: 1; +} + +.button-small { + padding: 12px 17px; + font-size: 12px; + gap: 23px; +} + +.text-link { + font-size: 12px; + font-weight: 600; + display: inline-flex; + gap: 16px; + align-items: center; + line-height: 1.8; +} + +.text-link:hover { + text-decoration: underline; + text-underline-offset: 5px; +} + +.skip-link { + position: fixed; + top: -70px; + left: 20px; + padding: 15px; + z-index: 10; + background: #fff; +} + +.skip-link:focus { + top: 10px; +} + +.site-header { + height: 99px; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid var(--line); +} + +.brand { + display: inline-flex; + align-items: center; + font-size: 22px; + font-weight: 650; + letter-spacing: -0.9px; +} + +.brand img { + margin-right: 11px; +} + +.brand span { + font-weight: 350; +} + +.site-header nav { + display: flex; + gap: 35px; + margin-left: 55px; + font-size: 12px; + font-weight: 500; +} + +:where(.site-header nav) a:hover { + text-decoration: underline; + text-underline-offset: 5px; +} + +.nav-github span { + margin-left: 5px; +} + +.hero { + display: grid; + grid-template-columns: 1fr 1.08fr; + gap: 42px; + align-items: center; + padding-block: 88px 86px; +} + +.hero h1 { + font-size: clamp(65px, 6.3vw, 90px); + line-height: 0.99; + letter-spacing: -4.5px; + margin-bottom: 28px; +} + +.hero-description { + color: var(--muted); + font-size: 16px; + max-width: 398px; + margin-bottom: 28px; +} + +.hero-description strong { + font-weight: 550; + color: var(--ink); +} + +.hero-actions { + display: flex; + align-items: center; + gap: 24px; +} + +.hero-footnote { + color: var(--muted); + font-size: 11px; + margin: 23px 0 0; +} + +.knowledge-map { + height: 540px; + position: relative; + isolation: isolate; + background-image: radial-gradient(#cdd4c2 1px, transparent 1px); + background-size: 18px 18px; + border-radius: 50%; +} + +.map-label { + position: absolute; + top: 3px; + left: 50%; + transform: translateX(-50%); + width: max-content; + font-size: 9px; + letter-spacing: 1.5px; + color: var(--muted); +} + +.map-orbit { + position: absolute; + border: 1px solid #dde1d2; + border-radius: 50%; + z-index: -1; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.orbit-one { + width: 370px; + height: 370px; +} + +.orbit-two { + width: 500px; + height: 500px; +} + +.map-connections { + position: absolute; + width: 100%; + height: 100%; + overflow: visible; +} + +.map-connections path { + stroke: #a3b294; + stroke-width: 1.3; + fill: none; +} + +.map-connections circle { + fill: #71945a; + stroke: var(--paper); + stroke-width: 3px; +} + +.map-node { + position: absolute; + display: flex; + align-items: center; + gap: 11px; + padding: 15px; + border: 1px solid #e0e4d7; + background: #fffef9; + box-shadow: 0 8px 24px #243b3210; + border-radius: 11px; + white-space: nowrap; + font-size: 13px; + font-weight: 600; +} + +.map-node small { + display: block; + color: var(--muted); + font-size: 9px; + font-weight: 400; + margin-top: 6px; +} + +.app-icon { + height: 44px; + width: 44px; + flex-shrink: 0; + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 29px; + border-radius: 12px; + font-weight: 400; + line-height: 1; + font-family: var(--sans); +} + +.lavender { + background: #e8e3f3; + color: #71618e; +} + +.peach { + background: #f7e2d2; + color: #a86d40; +} + +.sage { + background: #e0e9d5; + color: #547246; +} + +.blue { + background: #e0e9f4; + color: #617e9e; +} + +.yellow { + background: #f5edcc; + color: #92803a; +} + +.mint { + background: #deebdf; + color: #598164; +} + +.node-notes { + top: 83px; + left: 9%; + transform: rotate(-6deg); +} + +.node-todo { + top: 94px; + right: 4%; + transform: rotate(5deg); +} + +.node-readwise { + top: 243px; + left: -2%; + transform: rotate(-3deg); +} + +.node-stuff { + top: 260px; + right: -4%; + transform: rotate(4deg); +} + +.node-evernote { + top: 406px; + left: 8%; + transform: rotate(3deg); +} + +.node-ai { + top: 402px; + right: 4%; + transform: rotate(-5deg); +} + +.map-center { + position: absolute; + top: 180px; + left: 50%; + transform: translateX(-50%); + border: 6px solid var(--paper); + background: var(--green); + width: 172px; + height: 183px; + border-radius: 27px; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + justify-content: center; + color: #fffdf4; + box-shadow: 0 12px 30px #193e3326; +} + +.wp-mark { + display: grid; + place-content: center; + width: 31px; + height: 31px; + border: 1px solid #adbe9d; + border-radius: 50%; + font: + italic 23px Georgia, + serif; + color: var(--lime); + margin-bottom: 10px; +} + +.map-center strong { + font-size: 18px; + font-weight: 500; + line-height: 1.25; +} + +.map-center-caption { + font-size: 7px; + letter-spacing: 1.4px; + margin-top: 14px; + color: #d4dfcb; +} + +.map-footer { + position: absolute; + bottom: -19px; + text-align: center; + width: 100%; + font-size: 10px; + color: var(--muted); +} + +.principles { + border-top: 1px solid var(--line); + display: flex; + justify-content: space-between; + align-items: center; + gap: 24px; + padding-block: 29px 36px; + font-size: 11px; + color: var(--muted); +} + +.principles span { + display: flex; + align-items: center; + gap: 12px; +} + +.principles i { + font-size: 21px; + color: #53664a; + font-style: normal; +} + +.principles span:first-child i { + font-family: var(--serif); + font-style: italic; + border: 1px solid #8c9a84; + border-radius: 50%; + width: 25px; + height: 25px; + text-align: center; +} + +.knowledge-section { + background: var(--green); + color: #f8f8ef; + padding-block: 83px 64px; +} + +.knowledge-layout { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 58px 100px; + align-items: center; +} + +.knowledge-copy { + max-width: 440px; +} + +.knowledge-copy .eyebrow { + color: #becfac; +} + +.knowledge-copy h2 em, +.start-panel h2 em { + color: var(--lime); +} + +:where(.knowledge-copy) p:not(.eyebrow) { + color: #c2cfc4; + font-size: 14px; +} + +.light-link { + color: #eef5d4; + margin-top: 12px; +} + +.record-panel { + background: #f6f5ed; + color: var(--ink); + border-radius: 13px; + padding: 24px 27px; + box-shadow: 0 16px 50px #0a241d26; + transform: rotate(1deg); +} + +.record-header { + font-size: 8px; + letter-spacing: 1.3px; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid var(--line); + padding-bottom: 20px; + color: var(--muted); +} + +.record-title { + display: flex; + align-items: center; + gap: 13px; + margin: 25px 0; +} + +.record-title small { + font-size: 8px; + letter-spacing: 1.2px; + color: var(--muted); +} + +.record-title h3 { + font-family: var(--serif); + font-weight: 400; + font-size: 23px; + margin: 5px 0 0; + letter-spacing: -0.5px; +} + +.record-private { + margin-left: auto; + font-size: 9px; + padding: 4px 8px; + border: 1px solid var(--line); + border-radius: 4px; +} + +.record-fields { + font-size: 11px; +} + +.record-fields > div { + display: grid; + grid-template-columns: 115px 1fr; + gap: 10px; + padding: 14px 0; + border-top: 1px solid var(--line); +} + +.record-fields dt { + color: var(--muted); +} + +.record-fields dd { + margin: 0; +} + +.record-tag { + padding: 4px 6px; + background: #e8ebdf; + border-radius: 4px; + font-size: 9px; + display: inline-block; + margin: -4px 4px -4px 0; +} + +.record-endpoint { + display: flex; + align-items: center; + justify-content: space-between; + background: #e8ecdf; + border: 1px solid #dce3ce; + border-radius: 5px; + padding: 13px 12px; + gap: 12px; + font-size: 11px; + margin-top: 17px; +} + +.request-method { + font-size: 9px; + font-weight: 650; +} + +.record-note { + margin: 16px 0 0; + color: var(--muted); + font-size: 10px; + line-height: 1.6; +} + +.knowledge-details { + grid-column: 1 / -1; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 60px; + padding-top: 32px; + border-top: 1px solid #456153; +} + +.detail-number { + font-family: var(--serif); + font-style: italic; + font-size: 18px; + color: #bcd48b; +} + +.knowledge-details h3 { + font-size: 15px; + font-weight: 500; + margin: 14px 0 10px; +} + +.knowledge-details p { + color: #c2cfc4; + font-size: 12px; + margin-bottom: 0; +} + +.modules-section { + padding-block: 91px 65px; +} + +.section-heading { + display: flex; + justify-content: space-between; + align-items: flex-end; + gap: 40px; + margin-bottom: 38px; +} + +.section-heading h2 { + margin-bottom: 0; +} + +.section-heading > p { + max-width: 319px; + color: var(--muted); + font-size: 13px; + margin-bottom: 4px; +} + +.module-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 18px; +} + +.module-card { + padding: 27px; + border: 1px solid #dfe2d6; + background: #fcfcf7; + border-radius: 11px; + display: flex; + flex-direction: column; + transition: + border-color 180ms, + box-shadow 180ms; +} + +.module-card:hover { + border-color: #a5b498; + box-shadow: 0 6px 24px #193e3308; +} + +.stuff-card { + background: #edf0e2; + border-color: #bcc9a3; +} + +.card-top { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 24px; +} + +.module-kind { + font-size: 8px; + color: var(--muted); + letter-spacing: 1px; +} + +.module-kind .status-dot { + width: 4px; + height: 4px; + margin-right: 4px; +} + +.module-card h3 { + font-size: 20px; + font-weight: 500; + letter-spacing: -0.6px; + margin-bottom: 13px; +} + +.module-card > p { + font-size: 12px; + color: var(--muted); + margin-bottom: 21px; +} + +.module-card ul { + list-style: none; + padding: 0; + margin: 0 0 28px; + font-size: 10px; + line-height: 1.7; +} + +.module-card li { + padding-left: 13px; + position: relative; + margin-bottom: 7px; +} + +.module-card li::before { + content: "+"; + position: absolute; + left: 0; + color: #7b915d; +} + +.module-card > a { + margin-top: auto; + border-top: 1px solid var(--line); + padding-top: 17px; + font-size: 11px; + font-weight: 550; + display: flex; + justify-content: space-between; +} + +:where(.module-card) > a:hover { + color: #55703e; +} + +.module-card .arrow { + font-size: 16px; +} + +.module-note { + margin: 24px 0 0; + text-align: center; + font-size: 11px; + color: var(--muted); +} + +.module-note span { + font-size: 17px; + margin-right: 6px; +} + +.preview-section { + padding-block: 72px 66px; + background: #eeefe5; + border-top: 1px solid var(--line); + border-bottom: 1px solid var(--line); +} + +.preview-controls { + display: flex; + align-items: center; + gap: 8px; + margin: 36px 0 19px; +} + +.preview-controls button { + border: 1px solid transparent; + background: transparent; + display: flex; + align-items: center; + gap: 9px; + color: #55634d; + padding: 11px 17px; + border-radius: 6px; + font-size: 15px; +} + +.preview-controls .tab-label { + font-size: 12px; +} + +.preview-controls button[aria-selected="true"] { + color: #fff; + background: var(--green); + box-shadow: 0 2px 6px #193e3312; +} + +.preview-controls button:hover:not([aria-selected="true"]) { + background: #e1e6d6; +} + +.preview-label { + margin-left: auto; + font-size: 8px; + letter-spacing: 1.1px; + color: var(--muted); +} + +.browser-frame { + background: #fff; + border: 1px solid #d4dacb; + border-radius: 12px; + box-shadow: 0 22px 42px #193e330d; + overflow: hidden; +} + +.browser-chrome { + display: flex; + align-items: center; + justify-content: space-between; + padding: 13px 18px; + background: #f7f8f2; + border-bottom: 1px solid #dfe3d8; + font-size: 13px; + color: #74806b; +} + +.window-dots { + font-size: 10px; + letter-spacing: 3px; + color: #c4cbbc; +} + +.browser-address { + background: #ecefe5; + padding: 6px 60px; + border: 1px solid #e2e6da; + border-radius: 5px; + font-size: 9px; + color: #58634f; +} + +.browser-address span { + color: #41563d; +} + +.preview-panel { + aspect-ratio: 1440 / 900; +} + +.preview-panel img { + width: 100%; + height: auto; +} + +.preview-panel a { + display: block; +} + +.preview-caption { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 24px; + color: var(--muted); + margin-top: 19px; +} + +.preview-caption p { + font-size: 11px; + margin: 0; +} + +.preview-caption > span { + font-size: 7px; + letter-spacing: 1px; + white-space: nowrap; +} + +.ownership-section { + padding-block: 90px; +} + +.ownership-layout { + display: grid; + grid-template-columns: 1.1fr 1fr; + gap: 85px; +} + +.ownership-layout h2 { + margin-bottom: 0; +} + +.ownership-layout p { + font-size: 13px; + color: var(--muted); +} + +.start-section { + margin-bottom: 53px; +} + +.start-panel { + display: grid; + grid-template-columns: 1.15fr 1fr; + gap: 100px; + padding: 60px; + background: var(--green); + color: #f6f6ee; + border-radius: 15px; + position: relative; + overflow: hidden; +} + +.start-panel::after { + content: ""; + position: absolute; + height: 330px; + width: 330px; + border-radius: 50%; + border: 1px solid #53734c; + bottom: -270px; + left: 230px; + box-shadow: + 0 0 0 35px #ffffff03, + 0 0 0 70px #ffffff03; + pointer-events: none; +} + +.start-panel .eyebrow { + color: #c5d4b4; + font-size: 8px; +} + +.start-panel .status-dot { + background: var(--lime); +} + +.start-panel h2 { + font-size: 64px; + margin-bottom: 21px; +} + +:where(.start-panel) p:not(.eyebrow) { + color: #c2cfc4; + font-size: 13px; +} + +.start-actions { + display: flex; + gap: 25px; + align-items: center; + margin-top: 29px; +} + +.button-lime { + background: var(--lime); + color: var(--green); + border-color: var(--lime); +} + +.button-lime:hover { + background: #e1f5b4; +} + +.start-actions .text-link { + font-size: 10px; + margin-top: 0; + gap: 8px; +} + +.start-steps { + list-style: none; + padding: 8px 0 0; + margin: 0; +} + +.start-steps li { + display: flex; + align-items: flex-start; + gap: 20px; + padding: 23px 0; + border-bottom: 1px solid #44604f; +} + +.start-steps li:first-child { + padding-top: 0; +} + +.start-steps li:last-child { + padding-bottom: 0; + border: 0; +} + +.start-steps li > span { + color: #bed997; + font-family: var(--serif); + font-style: italic; + font-size: 18px; + line-height: 1.5; +} + +.start-steps h3 { + font-size: 15px; + font-weight: 500; + margin: 3px 0 8px; +} + +.start-steps p { + margin-bottom: 0; + font-size: 11px !important; +} + +.site-footer { + border-top: 1px solid var(--line); + padding-block: 34px 40px; + display: flex; + justify-content: space-between; + align-items: center; + gap: 30px; +} + +.site-footer .brand { + font-size: 19px; +} + +.site-footer p { + font-size: 10px; + color: var(--muted); + margin: 0; +} + +.site-footer p a { + color: var(--ink); + text-decoration: underline; + text-underline-offset: 3px; +} + +.site-footer > div { + text-align: right; +} + +.site-footer > div a { + font-size: 11px; +} + +.site-footer > div span { + display: block; + font-size: 7px; + color: var(--muted); + letter-spacing: 1.2px; + margin-top: 11px; +} + +[hidden] { + display: none !important; +} + +@media (min-width: 1500px) { + + .hero h1 { + font-size: 90px; + } +} + +@media (max-width: 1100px) { + + .wrap { + width: calc(100% - 64px); + } + + .hero { + gap: 15px; + } + + .hero h1 { + font-size: 72px; + } + + .hero-actions { + gap: 14px; + } + + .hero-actions .text-link { + font-size: 10px; + gap: 6px; + } + + .knowledge-map { + transform: scale(0.87); + transform-origin: center; + } + + .map-node { + padding: 12px 10px; + gap: 8px; + } + + .map-node small { + font-size: 8px; + } + + .node-readwise { + left: -8%; + } + + .node-stuff { + right: -10%; + } + + .knowledge-layout { + gap: 45px; + } + + .record-title h3 { + font-size: 19px; + } + + .record-fields > div { + grid-template-columns: 90px 1fr; + } + + .record-endpoint { + font-size: 9px; + } + + .module-card { + padding: 22px; + } + + .module-card h3 { + font-size: 18px; + } + + .start-panel { + padding: 45px; + gap: 45px; + } + + .start-actions { + flex-wrap: wrap; + gap: 16px; + } +} + +@media (max-width: 960px) { + + .wrap { + width: calc(100% - 48px); + } + + .site-header { + height: 83px; + } + + .site-header nav { + margin: 0; + gap: 20px; + } + + .site-header .button { + display: none; + } + + .hero { + grid-template-columns: 1fr; + padding-block: 65px 45px; + gap: 32px; + } + + .hero-copy { + max-width: 560px; + } + + .hero h1 { + font-size: 80px; + } + + .hero-description { + max-width: 440px; + } + + .hero-actions .text-link { + font-size: 12px; + gap: 16px; + } + + .hero-actions { + gap: 24px; + } + + .knowledge-map { + width: min(570px, 100%); + margin-inline: auto; + transform: none; + } + + .principles { + flex-wrap: wrap; + justify-content: flex-start; + gap: 23px 30px; + } + + .principles > span { + width: calc(50% - 15px); + } + + .knowledge-layout { + grid-template-columns: 1fr; + gap: 45px; + } + + .knowledge-copy { + max-width: 550px; + } + + .record-panel { + width: min(500px, 100%); + margin-inline: auto; + } + + .record-fields > div { + grid-template-columns: 115px 1fr; + } + + .record-title h3 { + font-size: 23px; + } + + .record-endpoint { + font-size: 11px; + } + + .knowledge-details { + gap: 24px; + } + + .section-heading { + align-items: flex-start; + flex-direction: column; + gap: 20px; + } + + .section-heading > p { + max-width: 480px; + } + + .module-grid { + grid-template-columns: repeat(2, 1fr); + } + + .module-card { + padding: 25px; + } + + .ownership-layout { + grid-template-columns: 1fr; + gap: 30px; + } + + .ownership-layout > div { + max-width: 580px; + } + + .start-panel { + grid-template-columns: 1fr; + padding: 40px; + gap: 40px; + } + + .start-actions { + flex-wrap: nowrap; + } + + .preview-caption { + flex-direction: column; + gap: 7px; + } + + .site-footer { + flex-wrap: wrap; + } +} + +@media (max-width: 520px) { + + .wrap { + width: calc(100% - 40px); + } + + .site-header { + height: 76px; + } + + .brand { + font-size: 20px; + } + + .brand img { + width: 28px; + height: 28px; + margin-right: 8px; + } + + .site-header nav { + gap: 16px; + font-size: 10px; + } + + .nav-github { + display: none; + } + + .hero { + padding-top: 48px; + gap: 33px; + } + + :where(.hero) .eyebrow { + font-size: 8px; + letter-spacing: 1.1px; + } + + .hero h1 { + font-size: 65px; + letter-spacing: -3.5px; + } + + .hero-description { + font-size: 14px; + } + + .hero-actions { + gap: 18px; + } + + .hero-actions .button { + font-size: 11px; + padding: 15px 17px; + gap: 14px; + } + + .hero-actions .text-link { + font-size: 10px; + gap: 7px; + } + + .knowledge-map { + height: 375px; + background-size: 15px 15px; + } + + .map-label { + font-size: 7px; + letter-spacing: 1.1px; + } + + .map-node { + padding: 9px; + gap: 7px; + font-size: 10px; + border-radius: 8px; + } + + .map-node .app-icon { + width: 30px; + height: 32px; + font-size: 21px; + border-radius: 8px; + } + + .map-node small { + display: none; + } + + .map-center { + top: 130px; + width: 132px; + height: 138px; + border-radius: 21px; + border-width: 4px; + } + + .map-center strong { + font-size: 14px; + } + + .wp-mark { + font-size: 19px; + width: 26px; + height: 26px; + margin-bottom: 7px; + } + + .map-center-caption { + font-size: 5px; + margin-top: 10px; + letter-spacing: 1px; + } + + .node-notes { + top: 68px; + left: 6%; + } + + .node-todo { + top: 68px; + right: 5%; + } + + .node-readwise { + top: 181px; + left: -1%; + } + + .node-stuff { + top: 191px; + right: -1%; + } + + .node-evernote { + top: 297px; + left: 5%; + } + + .node-ai { + top: 300px; + right: 4%; + } + + .orbit-one { + width: 245px; + height: 245px; + } + + .orbit-two { + width: 330px; + height: 330px; + max-width: 100%; + } + + .map-connections { + top: 6px; + } + + .map-footer { + bottom: -8px; + font-size: 7px; + } + + .principles { + font-size: 9px; + padding-block: 23px 28px; + gap: 18px 20px; + } + + .principles > span { + width: calc(50% - 10px); + gap: 8px; + } + + .principles i { + font-size: 18px; + } + + .principles span:first-child i { + width: 22px; + height: 22px; + } + + h2 { + font-size: 39px; + letter-spacing: -1.8px; + } + + .eyebrow { + font-size: 8px; + letter-spacing: 1.3px; + margin-bottom: 20px; + } + + .knowledge-section { + padding-block: 57px 44px; + } + + :where(.knowledge-copy) p:not(.eyebrow) { + font-size: 13px; + } + + .record-panel { + padding: 20px; + transform: none; + } + + .record-header { + font-size: 6px; + letter-spacing: 0.8px; + } + + .record-title { + gap: 10px; + } + + .record-title h3 { + font-size: 20px; + } + + .record-title .app-icon { + width: 36px; + height: 36px; + font-size: 23px; + } + + .record-private { + font-size: 7px; + } + + .record-fields { + font-size: 10px; + } + + .record-fields > div { + grid-template-columns: 90px 1fr; + gap: 7px; + } + + .record-tag { + font-size: 8px; + margin-right: 3px; + padding: 4px; + } + + .record-endpoint { + font-size: 9px; + padding-inline: 8px; + gap: 5px; + } + + .knowledge-details { + grid-template-columns: 1fr; + gap: 23px; + padding-top: 25px; + } + + .knowledge-details article { + position: relative; + padding-left: 34px; + } + + .detail-number { + position: absolute; + left: 0; + top: 0; + } + + .knowledge-details h3 { + margin-top: 2px; + } + + .modules-section { + padding-block: 58px 41px; + } + + .module-grid { + grid-template-columns: 1fr; + gap: 14px; + } + + .module-card { + padding: 26px; + } + + .module-card h3 { + font-size: 21px; + } + + .module-card > p { + font-size: 13px; + } + + .module-card ul { + font-size: 11px; + margin-bottom: 20px; + } + + .module-card > a { + font-size: 12px; + } + + .module-note { + font-size: 10px; + } + + .preview-section { + padding-block: 52px 40px; + } + + .preview-controls { + gap: 3px; + flex-wrap: wrap; + margin-top: 25px; + } + + .preview-controls button { + padding: 10px 16px; + } + + .preview-label { + margin: 10px 0 0; + width: 100%; + font-size: 7px; + } + + .browser-chrome { + padding: 9px 11px; + } + + .browser-address { + padding: 5px 15px; + font-size: 7px; + } + + .window-dots { + font-size: 7px; + letter-spacing: 1px; + } + + .browser-frame { + border-radius: 8px; + } + + .preview-caption p { + font-size: 10px; + } + + .preview-caption > span { + font-size: 6px; + } + + .ownership-section { + padding-block: 55px; + } + + .ownership-layout p { + font-size: 12px; + } + + .start-panel { + padding: 30px 25px; + border-radius: 11px; + gap: 32px; + } + + .start-panel h2 { + font-size: 58px; + } + + .start-panel .eyebrow { + font-size: 7px; + letter-spacing: 1px; + } + + .start-actions { + flex-wrap: wrap; + gap: 20px; + } + + .start-section { + margin-bottom: 34px; + } + + .site-footer { + padding-block: 28px; + gap: 22px; + } + + .site-footer > .brand { + width: 100%; + } + + .site-footer p { + font-size: 9px; + } + + .site-footer > div span { + font-size: 6px; + letter-spacing: 0.7px; + } +} + +@media (max-width: 360px) { + + .wrap { + width: calc(100% - 30px); + } + + .hero h1 { + font-size: 59px; + } + + .hero-actions { + gap: 12px; + } + + .hero-actions .button { + padding-inline: 12px; + } + + .hero-actions .text-link { + font-size: 9px; + } + + .record-panel { + padding: 16px; + } + + .record-private { + display: none; + } + + .record-fields > div { + grid-template-columns: 77px 1fr; + } + + .record-tag { + font-size: 7px; + } + + .site-footer > div { + text-align: left; + } +} + +@media (prefers-reduced-motion: reduce) { + + html { + scroll-behavior: auto; + } + + *, + *::before, + *::after { + transition: none !important; + } +} + +@media print { + + body { + background: #fff; + } + + .wrap { + width: 100%; + } + + .skip-link, + .preview-controls { + display: none; + } + + .knowledge-section, + .start-panel { + print-color-adjust: exact; + -webkit-print-color-adjust: exact; + } + + .module-card, + .record-panel { + break-inside: avoid; + } +}