/* ============================== THEME TOKENS ============================== */

/* Fonts, radii and the tab height: theme-independent design constants. */
:root{
  --mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  --serif-d:'Fraunces',Georgia,serif;
  --serif-b:'Newsreader',Georgia,serif;
  --sans:-apple-system,BlinkMacSystemFont,'Segoe UI','Noto Sans',Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji';
  --r:13px;
  --tab-h:40px;
}

/* "ink" = dark theme. bg-* are surfaces (deep→editor), text-* are foreground
   ramps, accent* are the orange/teal highlights, and t-* colour the markdown
   source view + code highlighter so both themes stay in sync. */
html[data-theme="ink"]{
  --bg-deep:#09080b;
  --bg-window:#17161c;
  --bg-panel:#121117;
  --bg-editor:#1a191f;
  --bg-tab:#121117;
  --bg-tab-active:#1a191f;
  --bg-hover:#211f28;
  --border:#2a2833;
  --border-soft:#201e27;
  --text:#e9e6df;
  --text-dim:#9b97a6;
  --text-faint:#5d5a68;
  --accent:#ff8a4c;
  --accent-2:#56c2c0;
  --accent-soft:rgba(255,138,76,.13);
  --t-heading:#ff8a4c;
  --t-strong:#f1c473;
  --t-link:#56c2c0;
  --t-url:#5d5a68;
  --t-codespan:#a6d676;
  --t-code:#9b97a6;
  --t-quote:#8f8aa0;
  --t-marker:#ff8a4c;
  --t-fence:#ff7a9c;
  --t-hr:#5d5a68;
  --grain:.035;
  color-scheme:dark;
}

/* "paper" = light theme: the same token set, warm-paper palette. */
html[data-theme="paper"]{
  --bg-deep:#d8d1c0;
  --bg-window:#fbf8f1;
  --bg-panel:#f0ebdf;
  --bg-editor:#fbf8f1;
  --bg-tab:#ece5d6;
  --bg-tab-active:#fbf8f1;
  --bg-hover:#ece5d6;
  --border:#ddd4c2;
  --border-soft:#e7e0d0;
  --text:#2a2722;
  --text-dim:#6f6a5d;
  --text-faint:#a8a08d;
  --accent:#c2510c;
  --accent-2:#0f7a78;
  --accent-soft:rgba(194,81,12,.12);
  --t-heading:#c2510c;
  --t-strong:#9a6b16;
  --t-link:#0f7a78;
  --t-url:#a8a08d;
  --t-codespan:#4a7d2c;
  --t-code:#6f6a5d;
  --t-quote:#7c7768;
  --t-marker:#c2510c;
  --t-fence:#b03a5b;
  --t-hr:#a8a08d;
  --grain:.025;
  color-scheme:light;
}

*{box-sizing:border-box;margin:0;padding:0}
::selection{background:var(--accent-soft);color:var(--text)}

/* ============================== BACKDROP ============================== */

html,body{height:100%}
body{
  font-family:var(--mono);
  background:var(--bg-deep);
  color:var(--text);
  overflow:hidden;
  position:relative;
}

/* Two soft accent glows over the deep background, behind everything. */
.backdrop{
  position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(900px 600px at 14% -8%, color-mix(in srgb,var(--accent) 22%,transparent), transparent 60%),
    radial-gradient(800px 700px at 100% 110%, color-mix(in srgb,var(--accent-2) 16%,transparent), transparent 55%),
    var(--bg-deep);
}

/* A subtle SVG noise grain laid over the glows (strength via --grain). */
.backdrop::after{
  content:"";position:absolute;inset:0;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity:var(--grain);mix-blend-mode:overlay;
}

/* ============================== WINDOW SHELL ============================== */

/* The stage centers the window over the backdrop. */
/* 100dvh tracks the visible viewport as mobile browser bars show/hide, so the
   bottom icon row is never behind the toolbar; 100vh is the fallback. */
.stage{position:relative;z-index:1;height:100vh;height:100dvh;display:flex;align-items:center;justify-content:center;padding:26px}
.window{
  width:100%;max-width:1180px;height:100%;max-height:780px;
  min-width:360px;min-height:420px;
  position:relative;z-index:2;

  /* chrome below adapts to THIS width, not the viewport */
  container:window / inline-size;
  display:flex;flex-direction:column;
  background:var(--bg-window);
  border:1px solid var(--border);
  border-radius:var(--r);
  overflow:hidden;
  box-shadow:0 1px 0 rgba(255,255,255,.04) inset, 0 40px 90px -30px rgba(0,0,0,.7), 0 10px 30px -15px rgba(0,0,0,.6);
  animation:rise .8s cubic-bezier(.16,1,.3,1) both;
}
@keyframes rise{from{opacity:0;transform:translateY(14px) scale(.992)}to{opacity:1;transform:none}}

/* Installed-app launches boot to the desktop (editor.js minimizes the window
   at boot). This guard keeps the server-rendered window from flashing before
   that deferred script runs; .js so a no-JS load still shows the site. */
@media(display-mode:standalone){html.js:not(.booted) .window{display:none}}

/* ---------- window states (driven by editor.js) ---------- */

/* free-floating; geometry set inline, no size cap */
.window.free{position:absolute;margin:0;max-width:none;max-height:none;animation:none}
.window.maximized{position:fixed;inset:0;width:auto;height:auto;min-width:0;min-height:0;max-width:none;max-height:none;border-radius:0;border:none;animation:none}
.window.hidden{display:none}
.window.dragging{transition:none;animation:none;-webkit-user-select:none;user-select:none}

/* resize grips on the frame (created by editor.js); container-type on .window
   makes it the containing block, so these anchor even while statically placed */
.win-handle{position:absolute;z-index:5;touch-action:none}
.win-handle.n{top:-3px;left:10px;right:10px;height:8px;cursor:ns-resize}
.win-handle.s{bottom:-3px;left:10px;right:10px;height:8px;cursor:ns-resize}
.win-handle.e{top:10px;bottom:10px;right:-3px;width:8px;cursor:ew-resize}
.win-handle.w{top:10px;bottom:10px;left:-3px;width:8px;cursor:ew-resize}
.win-handle.ne{top:-4px;right:-4px;width:16px;height:16px;cursor:nesw-resize}
.win-handle.sw{bottom:-4px;left:-4px;width:16px;height:16px;cursor:nesw-resize}
.win-handle.nw{top:-4px;left:-4px;width:16px;height:16px;cursor:nwse-resize}
.win-handle.se{bottom:-4px;right:-4px;width:16px;height:16px;cursor:nwse-resize}
.window.maximized .win-handle{display:none}

/* macOS dots are real buttons now */
.dot{padding:0;cursor:pointer;-webkit-appearance:none;appearance:none;transition:filter .12s}
.dot:hover{filter:brightness(1.15)}
.dot:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* ---------- title bar ---------- */

.titlebar{
  height:38px;flex:none;display:flex;align-items:center;gap:14px;padding:0 14px;
  background:var(--bg-panel);border-bottom:1px solid var(--border-soft);
  -webkit-user-select:none;user-select:none;
}
.dots{display:flex;gap:8px}
.dot{width:12px;height:12px;border-radius:50%;border:1px solid rgba(0,0,0,.18)}
.dot.r{background:#ff5f57}.dot.y{background:#febc2e}.dot.g{background:#28c840}
.titlebar .who{
  margin-left:4px;font-size:12px;color:var(--text-dim);letter-spacing:.02em;
  display:flex;align-items:center;gap:8px;
}
.titlebar .who b{color:var(--text);font-weight:500}
.titlebar .who .sep{color:var(--text-faint)}
.titlebar .right{margin-left:auto;display:flex;align-items:center;gap:6px}
.iconbtn{
  width:28px;height:28px;display:grid;place-items:center;border:none;cursor:pointer;
  background:transparent;color:var(--text-dim);border-radius:7px;transition:.15s;
}
.iconbtn:hover{background:var(--bg-hover);color:var(--text)}
.iconbtn svg{width:15px;height:15px}

/* The tour replay button is mobile-only (shown in the mobile media block):
   the guided tour explains the touch UI and never runs on desktop. */
#btn-tour{display:none}

/* ============================== BODY ============================== */

/* Activity bar | sidebar | main, filling the window below the titlebar. */
.body{flex:1;display:flex;min-height:0}

/* ---------- activity bar ---------- */

.activity{
  width:48px;flex:none;background:var(--bg-panel);border-right:1px solid var(--border-soft);
  display:flex;flex-direction:column;align-items:center;padding:10px 0;gap:4px;
}
.act{
  width:38px;height:38px;display:grid;place-items:center;border:none;background:transparent;
  color:var(--text-faint);cursor:pointer;border-radius:9px;position:relative;transition:.15s;text-decoration:none;
}
.act:hover{color:var(--text)}
.act.on{color:var(--accent)}
.act.on::before{content:"";position:absolute;left:-10px;top:9px;bottom:9px;width:2px;border-radius:2px;background:var(--accent)}
.act svg{width:20px;height:20px}
.act .badge{position:absolute;top:5px;right:4px;width:7px;height:7px;border-radius:50%;background:var(--accent);box-shadow:0 0 0 2px var(--bg-panel)}
.activity .spacer{flex:1}

/* ---------- sidebar ---------- */

.sidebar{
  width:248px;flex:none;background:var(--bg-panel);border-right:1px solid var(--border-soft);
  display:flex;flex-direction:column;overflow:hidden;transition:width .22s cubic-bezier(.16,1,.3,1),opacity .18s;
}

/* Collapsed: width animates to 0 (toggled from editor.js / Ctrl+B). */
.sidebar.collapsed{width:0;opacity:0;border-right-color:transparent}
.sb-head{
  padding:13px 16px 9px;font-size:11px;letter-spacing:.16em;color:var(--text-faint);text-transform:uppercase;
  display:flex;align-items:center;justify-content:space-between;
}
.sb-proj{padding:4px 12px 8px;display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--text);font-weight:500;cursor:pointer;-webkit-user-select:none;user-select:none}
.sb-proj:hover .chev{color:var(--text)}
.sb-proj:focus-visible{outline:none}
.sb-proj:focus-visible .chev{color:var(--accent)}
.sb-proj>svg{width:13px;height:13px;color:var(--accent)}
.sb-proj .chev{width:14px;height:14px;flex:none;display:grid;place-items:center;color:var(--text-dim);transition:transform .15s ease}
.sb-proj .chev svg{width:12px;height:12px}
.sb-proj.collapsed .chev{transform:rotate(-90deg)}
.tree{flex:1;overflow-y:auto;padding:0 6px 12px}
.tree::-webkit-scrollbar{width:11px;height:11px}
.tree::-webkit-scrollbar-thumb{background:var(--border);border-radius:6px;border:3px solid var(--bg-panel)}
.tree::-webkit-scrollbar-thumb:hover{background:var(--text-faint)}

/* A tree row (file or folder); rows slide in on load. */
.node{
  display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:7px;cursor:pointer;
  font-size:12.5px;color:var(--text-dim);position:relative;transition:background .12s,color .12s;
  text-decoration:none;
  opacity:0;animation:slidein .5s cubic-bezier(.16,1,.3,1) forwards;
}
@keyframes slidein{from{opacity:0;transform:translateX(-8px)}to{opacity:1;transform:none}}
.node:hover{background:var(--bg-hover);color:var(--text)}
.node.active{background:var(--accent-soft);color:var(--text)}
.node.active::before{content:"";position:absolute;left:0;top:6px;bottom:6px;width:2px;border-radius:2px;background:var(--accent)}
.node .ix{width:15px;display:grid;place-items:center;flex:none}
.node .ix svg{width:13px;height:13px}
.node.folder{color:var(--text)}
.node.folder .ix svg{color:var(--accent-2)}
.node.indent{margin-left:14px}
.node.more{color:var(--text-faint)}
.node.more:hover{color:var(--text)}
.node.more .more-ix{width:16px;flex:none;display:grid;place-items:center;color:var(--text-faint);font-weight:700;letter-spacing:1px}

/* The "MD" file-type badge. */
.fileicon{
  font-size:8px;font-weight:700;letter-spacing:.02em;width:16px;height:16px;border-radius:3px;
  display:grid;place-items:center;flex:none;background:color-mix(in srgb,var(--accent) 18%,transparent);color:var(--accent);
}
.children{overflow:hidden;transition:height .2s ease;position:relative}
.children::before{content:"";position:absolute;left:22px;top:1px;bottom:1px;width:1px;background:var(--border-soft)}
.children.closed{display:none}
/* The tree ships expanded so it works without JS. When JS is available, collapse
   the folders before editor.js runs (which then marks #tree.ready) to avoid a
   flash of the full menu. */
html.js .tree:not(.ready) .children{display:none}

/* folder twisties (VS Code-style): empty slot on files keeps icons aligned */
.node .chev{width:16px;flex:none;display:grid;place-items:center;margin-right:-2px;color:var(--text-faint);transition:transform .15s ease}
.node .chev svg{width:12px;height:12px}
.node.folder:hover .chev{color:var(--text)}
.node.folder.collapsed .chev{transform:rotate(-90deg)}
html.js .tree:not(.ready) .node.folder .chev{transform:rotate(-90deg)}
.tree.tree-collapsed{display:none}

/* ---------- main ---------- */

.main{flex:1;display:flex;flex-direction:column;min-width:0;background:var(--bg-editor);position:relative}

/* tabs */
.tabs{height:var(--tab-h);flex:none;display:flex;background:var(--bg-tab);border-bottom:1px solid var(--border-soft);overflow:visible;position:relative}
.tabstrip{display:flex;min-width:0;flex:1;overflow:hidden}
.tab{
  display:flex;align-items:center;gap:8px;padding:0 12px 0 14px;height:100%;cursor:pointer;flex:none;
  border-right:1px solid var(--border-soft);font-size:12.5px;color:var(--text-dim);
  background:var(--bg-tab);white-space:nowrap;position:relative;transition:color .12s;max-width:230px;text-decoration:none;
  /* Tabs are long-pressable (context menu): no iOS link callout, no selection. */
  -webkit-touch-callout:none;-webkit-user-select:none;user-select:none;
}
.tab:hover{color:var(--text)}
.tab.active{background:var(--bg-tab-active);color:var(--text)}
.tab.active::after{content:"";position:absolute;top:0;left:0;right:0;height:2px;background:var(--accent)}
.tab .nm{overflow:hidden;text-overflow:ellipsis}
.tab .mod{width:7px;height:7px;border-radius:50%;background:var(--text-faint)}
.tab .x{width:18px;height:18px;display:grid;place-items:center;border-radius:5px;color:var(--text-faint);opacity:1;transition:.12s}
.tab .x:hover{background:var(--bg-hover);color:var(--text)}
.tab .x svg{width:11px;height:11px}

/* Tabs that don't fit are hidden by editor.js and listed in the overflow menu. */
.tab.ovf-hidden{display:none}

/* overflow control + dropdown */
.tabovf{flex:none;display:flex;align-items:center;gap:6px;height:100%;padding:0 13px;cursor:pointer;
  border:none;border-left:1px solid var(--border-soft);background:var(--bg-tab-active);color:var(--text);font:inherit}
.tabovf[hidden]{display:none}
.tabovf:hover{background:var(--bg-hover)}
.tabovf:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.tabovf .chev{width:15px;height:15px;transition:transform .15s ease}
.tabovf.open .chev{transform:rotate(180deg)}
.tabovf .tabovf-n{display:grid;place-items:center;min-width:18px;height:18px;padding:0 5px;border-radius:9px;
  background:var(--accent);color:#1a1208;font-size:11px;font-weight:600;line-height:1}
html[data-theme="paper"] .tabovf .tabovf-n{color:#fff}
.tabmenu{position:absolute;right:0;top:100%;z-index:30;min-width:200px;max-width:300px;max-height:60vh;overflow-y:auto;
  background:var(--bg-window);border:1px solid var(--border);border-radius:10px;padding:6px;margin-top:4px;
  box-shadow:0 24px 60px -20px rgba(0,0,0,.7)}
.tabmenu[hidden]{display:none}
.tabmenu .item{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:7px;cursor:pointer;
  font-size:12.5px;color:var(--text-dim);text-decoration:none}
.tabmenu .item:hover,.tabmenu .item:focus-visible{background:var(--bg-hover);color:var(--text);outline:none}
.tabmenu .item.active{color:var(--text)}
.tabmenu .item.active::before{content:"";width:3px;align-self:stretch;margin:-8px 2px -8px -4px;border-radius:2px;background:var(--accent)}
.tabmenu .item .nm{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tabmenu .item .x{width:18px;height:18px;flex:none;display:grid;place-items:center;border-radius:5px;color:var(--text-faint);opacity:.6;transition:.12s}
.tabmenu .item:hover .x{opacity:1}
.tabmenu .item .x:hover{background:var(--bg-hover);color:var(--text)}
.tabmenu .item .x svg{width:11px;height:11px}

/* Right-click / long-press tab menu: the overflow dropdown look, floating at
   the pointer. Appended to body, so it needs to clear the stage (z-index:1)
   and the command palette (50). */
.tabmenu.ctx{position:fixed;right:auto;top:auto;z-index:60;min-width:150px}

/* breadcrumb / viewbar */
.viewbar{
  height:34px;flex:none;display:flex;align-items:center;gap:6px;padding:0 16px;
  border-bottom:1px solid var(--border-soft);background:var(--bg-editor);font-size:11.5px;color:var(--text-faint);
}
.crumb{display:flex;align-items:center;gap:7px;min-width:0}
.crumb .c{white-space:nowrap}
.crumb .c.last{color:var(--text-dim)}
.crumb .car{opacity:.5}

/* The Preview / Source segmented control, pushed to the right of the viewbar. */
.seg{margin-left:auto;display:flex;background:var(--bg-panel);border:1px solid var(--border);border-radius:8px;padding:2px;gap:2px}
.seg button{
  border:none;background:transparent;color:var(--text-dim);font-family:var(--mono);font-size:11px;
  padding:3px 11px;border-radius:6px;cursor:pointer;transition:.14s;letter-spacing:.02em;
}
.seg button.on{background:var(--accent);color:#1a1208}
html[data-theme="paper"] .seg button.on{color:#fff}
.seg[hidden]{display:none}

/* copy-source button (Source view): floats over the editor pane. */
.srccopy{
  display:flex;align-items:center;justify-content:center;
  width:30px;height:30px;padding:0;border:1px solid var(--border);border-radius:6px;
  background:var(--bg-window);color:var(--text-dim);cursor:pointer;
  transition:opacity .12s,color .12s,border-color .12s;
}
.srccopy:hover{color:var(--text);border-color:var(--accent)}
.srccopy:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.srccopy.ok{color:var(--accent-2);border-color:var(--accent-2)}
.srccopy svg{width:15px;height:15px;display:block}
.srccopy[hidden]{display:none}

/* pinned to the top-right of the editor pane; anchored to .main (which does
   not scroll), so it stays put while the source scrolls beneath it. The offset
   clears the tabs (--tab-h) and the 34px viewbar. */
.srccopy-float{position:absolute;top:calc(var(--tab-h) + 44px);right:18px;z-index:5;opacity:.6}
.srccopy-float:hover,.srccopy-float:focus-visible{opacity:1}

/* editor scroll area */
.editor-wrap{flex:1;overflow:auto;position:relative}
.editor-wrap::-webkit-scrollbar{width:11px;height:11px}
.editor-wrap::-webkit-scrollbar-thumb{background:var(--border);border-radius:6px;border:3px solid var(--bg-editor)}
.editor-wrap::-webkit-scrollbar-thumb:hover{background:var(--text-faint)}

/* ---------- SOURCE VIEW ---------- */

/* Line-numbered raw markdown; each .row is a gutter (.ln) + content (.lc). */
.source{font-size:13px;line-height:1.7;padding:14px 0 60px;min-width:max-content}
.source[hidden]{display:none}
.source .row{display:flex;animation:fadein .4s ease both}
.source .ln{
  width:52px;flex:none;text-align:right;padding-right:18px;color:var(--text-faint);
  -webkit-user-select:none;user-select:none;opacity:.65;font-variant-numeric:tabular-nums;
}
.source .lc{white-space:pre;padding-right:40px;color:var(--text)}

/* Source highlighter tokens (set by highlightMd in editor.js). */
.t-heading{color:var(--t-heading);font-weight:700}
.t-strong{color:var(--t-strong);font-weight:500}
.t-link{color:var(--t-link)}
.t-url{color:var(--t-url)}
.t-codespan{color:var(--t-codespan)}
.t-code{color:var(--t-code)}
.t-quote{color:var(--t-quote);font-style:italic}
.t-marker{color:var(--t-marker);font-weight:700}
.t-fence{color:var(--t-fence)}
.t-hr{color:var(--t-hr)}

/* ---------- PREVIEW (rendered prose) ---------- */

.prose{max-width:948px;margin-inline:auto;padding:clamp(24px,3vw,44px);width:100%;box-sizing:border-box}
.prose[hidden]{display:none}
.prose>*{max-width:none}
@keyframes fadein{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* Stagger the fade-in of the first few top-level blocks. */
.prose>*{animation:fadein .5s cubic-bezier(.16,1,.3,1) both}
.prose>*:nth-child(1){animation-delay:.02s}
.prose>*:nth-child(2){animation-delay:.06s}
.prose>*:nth-child(3){animation-delay:.10s}
.prose>*:nth-child(4){animation-delay:.14s}
.prose>*:nth-child(5){animation-delay:.18s}
.prose>*:nth-child(n+6){animation-delay:.22s}

/* GitHub / VSCode-flavored Markdown rendering (themed with the site tokens) */
.prose{font-family:var(--sans);font-size:14px;line-height:1.6;color:var(--text)}
.prose>*:first-child{margin-top:0!important}
.prose h1,.prose h2,.prose h3,.prose h4,.prose h5,.prose h6{
  font-family:var(--sans);font-weight:600;line-height:1.25;letter-spacing:normal;
  color:var(--text);margin:24px 0 16px;
}
.prose h1{font-size:2em;padding-bottom:.3em;border-bottom:1px solid var(--border)}
.prose h2{font-size:1.5em;padding-bottom:.3em;border-bottom:1px solid var(--border)}
.prose h3{font-size:1.25em}
.prose h4{font-size:1em;text-transform:none;letter-spacing:normal;color:var(--text)}
.prose h5{font-size:.875em}
.prose h6{font-size:.85em;color:var(--text-dim)}
.prose p,.prose li{font-family:var(--sans);font-size:14px;line-height:1.6;color:var(--text);font-weight:400}
.prose p{margin:0 0 16px}
.prose strong{font-weight:600;color:var(--text)}
.prose em{font-style:italic}

/* Prose links, excluding the structural link types (file rows, tags, pager). */
.prose a:not(.filerow-link):not(.tg):not(.pager-link){color:var(--accent);text-decoration:none;border-bottom:none;padding-bottom:0}
.prose a:not(.filerow-link):not(.tg):not(.pager-link):hover{text-decoration:underline;background:none}
.prose ul,.prose ol{margin:0 0 16px;padding-left:2em}
.prose ul ul,.prose ul ol,.prose ol ol,.prose ol ul{margin:0}
.prose li{margin:.25em 0}
.prose li>p{margin:.25em 0}
.prose ul li::marker{color:var(--text-dim)}
.prose ol li::marker{color:var(--text-dim);font-family:inherit;font-size:1em}
.prose blockquote{
  margin:0 0 16px;padding:0 1em;border-left:.25em solid var(--border);
  font-family:var(--sans);font-style:normal;font-size:14px;color:var(--text-dim);
}
.prose blockquote>:first-child{margin-top:0}
.prose blockquote>:last-child{margin-bottom:0}
.prose blockquote p{margin:0 0 16px;font-style:normal}

/* Inline code: tinted chip. */
.prose code{
  font-family:var(--mono);font-size:85%;background:color-mix(in srgb,var(--text-dim) 22%,transparent);
  color:var(--text);padding:.2em .4em;border-radius:6px;border:none;
}

/* Fenced code block container. */
.prose pre{
  font-family:var(--mono);background:var(--bg-panel);border:1px solid var(--border);border-radius:8px;
  margin:0 0 16px;padding:16px;overflow-x:auto;max-width:none;line-height:1.45;
}

/* Code inside a block: reset the inline-code chip styling. */
.prose pre code{background:none;border:none;padding:0;color:var(--text);font-size:85%;line-height:inherit;white-space:pre}

/* Notice banner: code-block box, accent-tinted, with larger type. */
.prose .notice{
  font-family:var(--mono);background:color-mix(in srgb,var(--accent) 9%,var(--bg-panel));
  border:1px solid color-mix(in srgb,var(--accent) 35%,var(--border));border-left:3px solid var(--accent);border-right:3px solid var(--accent);
  border-radius:8px;margin:0 0 24px;padding:16px 18px;line-height:1.5;
  display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 12px;
}
.prose .notice-tag{
  font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.14em;
  color:var(--accent);text-transform:uppercase;flex:none;
}
.prose .notice-msg{font-size:1.05em;color:var(--text)}
.prose .notice-msg code{font-size:90%}
.prose .notice-msg a{color:var(--accent)}
.prose hr{border:0;height:.25em;background:var(--border);margin:24px 0}
.prose hr::after{content:none}
.prose table{border-collapse:collapse;margin:0 0 16px;font-family:var(--sans);font-size:14px;width:auto;max-width:100%;display:block;overflow:auto}
.prose th,.prose td{border:1px solid var(--border);padding:6px 13px;text-align:left}
.prose th{background:var(--bg-panel);color:var(--text);font-weight:600;letter-spacing:normal}
.prose tr:nth-child(2n){background:var(--bg-panel)}
.prose img{max-width:100%;border-radius:6px;margin:0 0 16px;border:none;background:var(--bg-window)}

/* client-side code highlight tokens (theme-aware via --t-* variables) */
.prose pre{position:relative}
.prose pre code .hl-c{color:var(--t-quote);font-style:italic}
.prose pre code .hl-s{color:var(--t-codespan)}
.prose pre code .hl-n{color:var(--t-strong)}
.prose pre code .hl-k{color:var(--t-fence)}
.prose pre code .hl-cn{color:var(--t-strong)}
.prose pre code .hl-f{color:var(--t-link)}
.prose pre code .hl-t{color:var(--t-heading)}

/* Per-block copy button (added by editor.js); fades in on block hover. */
.copybtn{
  position:absolute;top:8px;right:8px;display:flex;align-items:center;justify-content:center;
  width:30px;height:30px;padding:0;border:1px solid var(--border);border-radius:6px;
  background:var(--bg-window);color:var(--text-dim);cursor:pointer;opacity:.5;
  transition:opacity .12s,color .12s,border-color .12s;
}
.prose pre:hover .copybtn,.copybtn:hover,.copybtn:focus-visible{opacity:1}
.copybtn:hover{color:var(--text);border-color:var(--accent)}
.copybtn.ok{color:var(--accent-2);border-color:var(--accent-2);opacity:1}
.copybtn svg{width:15px;height:15px;display:block}

/* Tag pills appended to a post. */
.prose .post-tags{display:flex;flex-wrap:wrap;gap:8px;margin:2.4rem 0 0;max-width:860px}
.prose .post-tags a{font-family:var(--mono);font-size:11.5px;color:var(--accent-2);text-decoration:none;
  background:color-mix(in srgb,var(--accent-2) 12%,transparent);border:1px solid color-mix(in srgb,var(--accent-2) 28%,transparent);
  border-radius:20px;padding:3px 12px;transition:.14s}
.prose .post-tags a:hover{background:color-mix(in srgb,var(--accent-2) 24%,transparent)}
.prose .form-placeholder{
  font-family:var(--mono);font-size:.9rem;color:var(--text-dim);max-width:860px;
  margin:1.5rem 0;padding:1.1rem 1.3rem;border:1px dashed var(--border);border-radius:10px;
  background:var(--bg-panel);
}
.prose .form-placeholder strong{color:var(--accent);font-weight:500}

/* ---------- section index (file listing) ---------- */

.filelist{margin:1.8rem 0 0;border-top:1px solid var(--border-soft)}
.filelist .filerow{
  position:relative;display:flex;flex-direction:column;padding:14px 8px;
  border-bottom:1px solid var(--border-soft);text-decoration:none;color:inherit;
  border-radius:8px;transition:background .12s,border-color .12s;
}

/* the title is the post link; its ::after stretches over the whole row so the
   card stays fully clickable, while the tag links (raised above it) keep their
   own clicks */
.filelist .filerow-link{text-decoration:none;color:inherit}
.filelist .filerow-link::after{content:"";position:absolute;inset:0;z-index:0}
.filelist .filerow:hover{background:var(--bg-hover);border-bottom-color:var(--accent)}
.filelist .filerow-title{
  font-family:var(--sans);font-weight:600;font-size:1.15rem;line-height:1.25;
  color:var(--text);margin:0;transition:color .12s;
}
.filelist .filerow:hover .filerow-title{color:var(--accent)}
.filelist .filerow-name{
  display:inline-flex;align-items:center;gap:7px;align-self:flex-start;
  font-family:var(--mono);font-size:11px;color:var(--text-faint);margin:.4rem 0 0;
  word-break:break-all;
}
.filelist .filerow-desc{
  font-family:var(--sans);font-size:.95rem;line-height:1.55;color:var(--text-dim);margin:.6rem 0 0;
}
.filelist .filerow-meta{display:flex;flex-wrap:wrap;align-items:center;gap:12px;font-family:var(--mono);font-size:11px;color:var(--text-faint);margin:.6rem 0 0}
.filelist .filerow-meta time{color:var(--text-dim);font-variant-numeric:tabular-nums}

/* Tag links sit above the row's full-card link so they stay individually clickable. */
.filelist .filerow-meta .tg{position:relative;z-index:1;color:var(--accent-2);text-decoration:none;transition:color .12s}
.filelist .filerow-meta .tg:hover{color:var(--accent);text-decoration:underline}
.pager{display:flex;align-items:center;justify-content:center;gap:18px;margin:2.2rem 0 0;max-width:860px}
.pager-link{font-family:var(--mono);font-size:12px;color:var(--accent);text-decoration:none;padding:5px 12px;border-radius:7px;transition:background .12s}
.pager-link:hover{background:var(--accent-soft)}
.pager-link.disabled{color:var(--text-faint);pointer-events:none}
.pager-pos{font-family:var(--mono);font-size:11px;color:var(--text-faint);font-variant-numeric:tabular-nums}

/* ---------- status bar ---------- */

.statusbar{
  height:25px;flex:none;display:flex;align-items:center;gap:0;background:var(--accent);color:#1a1208;
  font-size:11px;letter-spacing:.01em;
}
html[data-theme="paper"] .statusbar{color:#fff}
.statusbar .si{display:flex;align-items:center;gap:5px;padding:0 11px;height:100%;white-space:nowrap;text-decoration:none;color:inherit}
.statusbar .si svg{width:12px;height:12px}
.statusbar .si.hov{cursor:pointer;transition:background .12s}
.statusbar .si.hov:hover{background:rgba(0,0,0,.12)}
.statusbar .grow{flex:1}
.statusbar .si.ghost{background:rgba(0,0,0,.14)}

/* ---------- welcome / empty state (all tabs closed) ---------- */

.welcome{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;color:var(--text-faint);text-align:center;padding:30px}
.welcome[hidden]{display:none}
.welcome .logo{font-family:var(--serif-d);font-size:3.4rem;color:var(--text);letter-spacing:-.03em}
.welcome .logo b{color:var(--accent)}
.welcome .hint{font-size:13px;line-height:2}
.welcome kbd{font-family:var(--mono);background:var(--bg-panel);border:1px solid var(--border);border-bottom-width:2px;border-radius:6px;padding:2px 7px;color:var(--text-dim);font-size:11px}

/* Blinking caret after the hint text. */
.cursor{display:inline-block;width:9px;height:1.1em;background:var(--accent);margin-left:2px;vertical-align:-2px;animation:blink 1.1s steps(1) infinite}
@keyframes blink{50%{opacity:0}}

/* ============================== COMMAND PALETTE ============================== */

.palette-bg{position:fixed;inset:0;z-index:50;background:rgba(0,0,0,.45);backdrop-filter:blur(3px);display:none;align-items:flex-start;justify-content:center;padding-top:14vh}
.palette-bg.open{display:flex;animation:pfade .15s ease}
@keyframes pfade{from{opacity:0}to{opacity:1}}
.palette{
  width:min(560px,92vw);background:var(--bg-window);border:1px solid var(--border);border-radius:13px;
  box-shadow:0 30px 70px -20px rgba(0,0,0,.7);overflow:hidden;animation:pslide .2s cubic-bezier(.16,1,.3,1)
}
@keyframes pslide{from{opacity:0;transform:translateY(-10px) scale(.98)}to{opacity:1;transform:none}}
.palette input{
  width:100%;border:none;background:transparent;color:var(--text);font-family:var(--mono);font-size:14px;
  padding:16px 18px;outline:none;border-bottom:1px solid var(--border-soft)
}
.palette input::placeholder{color:var(--text-faint)}
.plist{max-height:330px;overflow-y:auto;padding:6px}
.pitem{display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:8px;cursor:pointer;font-size:13px;color:var(--text-dim);text-decoration:none}
.pitem .sub{margin-left:auto;font-size:11px;color:var(--text-faint)}
.pitem.sel{background:var(--accent-soft);color:var(--text)}
.pitem .fileicon{font-size:8px}
.pfoot{padding:8px 14px;border-top:1px solid var(--border-soft);font-size:10.5px;color:var(--text-faint);display:flex;gap:16px}
.pfoot kbd{font-family:var(--mono);background:var(--bg-panel);border:1px solid var(--border);border-radius:4px;padding:1px 5px}

/* ============================== DESKTOP ICONS ============================== */

/* Full-stage layer behind the window. Transparent + non-interactive so the
   window stays clickable; only the icons themselves capture pointer events. */
.desktop{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden}

/* Wallpaper wordmark, centered behind the icons (they are absolute and paint
   above it). Inherits the layer's pointer-events:none, so it never blocks a
   click; the window (z-index:2) covers it whenever one is open. */
/* Each theme prints the wordmark in the other theme's window colour: light
   ink on the dark desktop, dark ink on the light one. */
.desk-wall{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  color:#fbf8f1;font-family:var(--mono);font-weight:700;font-size:clamp(2.2rem,6vw,3.4rem);
}
html[data-theme="paper"] .desk-wall{color:#17161c}
.desk-wall b{color:var(--accent)}

.desk-icon{
  position:absolute;pointer-events:auto;width:72px;
  display:flex;flex-direction:column;align-items:center;gap:7px;padding:9px 5px 7px;
  background:transparent;border:1px solid transparent;border-radius:11px;cursor:pointer;
  color:var(--text-dim);font-family:var(--mono);font-size:11px;letter-spacing:.01em;text-align:center;
  -webkit-appearance:none;appearance:none;touch-action:none;
  -webkit-user-select:none;user-select:none;transition:background .12s,border-color .12s,color .12s;
}
.desk-icon:hover{background:var(--bg-hover);color:var(--text)}
.desk-icon:focus-visible{outline:none;border-color:var(--accent);color:var(--text)}
.desk-icon.dragging{z-index:10;background:var(--bg-hover);color:var(--text);box-shadow:0 14px 34px -14px rgba(0,0,0,.6)}
.desk-icon[hidden]{display:none}
.desk-glyph{
  width:44px;height:44px;display:grid;place-items:center;border-radius:12px;
  background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent);
  border:1px solid color-mix(in srgb,var(--accent) 26%,transparent);
}
.desk-glyph svg{width:32px;height:32px}

/* The theme icon shows the current theme's glyph. Moon is the default so a
   missing data-theme (pre-boot) still renders exactly one glyph. */
html[data-theme="paper"] #icon-theme .g-moon,
html:not([data-theme="paper"]) #icon-theme .g-sun{display:none}
.desk-label{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.2}

/* ============================== MINI-APP WINDOWS ============================== */

/* App windows reuse .window/.window.free but float free and size to content
   (dialog) or to an inline default (window-kind), so the kernel's fixed
   width/height/min caps are reset here. */
.window.app{
  width:auto;height:auto;max-width:none;max-height:none;
  min-width:280px;min-height:0;
  animation:appin .24s cubic-bezier(.16,1,.3,1) both;
}
@keyframes appin{from{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:none}}

/* The focused app window gets a stronger shadow + an accent hairline. */
.window.app.focused{
  box-shadow:0 1px 0 rgba(255,255,255,.05) inset,0 50px 110px -30px rgba(0,0,0,.8),0 14px 40px -16px rgba(0,0,0,.7);
  outline:1px solid color-mix(in srgb,var(--accent) 28%,transparent);
}
.window.app .titlebar .who b{color:var(--text)}

/* Window-kind body: the content host fills the area below the titlebar. */
.window.app .main.app-host{background:var(--bg-editor);overflow:auto}

/* Dialog: title + message + a right-aligned button row, no status bar.
   touch-action lets the titlebar drag own touch gestures (mobile drag). */
.window.app.dialog{min-width:300px}
.window.app.dialog .titlebar{touch-action:none}
.window.app.dialog .dialog-body{
  flex:1;min-height:40px;padding:22px 22px 8px;
  font-family:var(--sans);font-size:14px;line-height:1.6;color:var(--text);
}
.window.app.dialog .dialog-actions{
  flex:none;display:flex;justify-content:flex-end;gap:10px;padding:14px 18px 18px;
}

/* Dialog / app buttons (also used by api.createDialog). */
.dlg-btn{
  font-family:var(--mono);font-size:12px;padding:7px 16px;border-radius:8px;cursor:pointer;
  border:1px solid var(--border);background:var(--bg-panel);color:var(--text);transition:.14s;
}
.dlg-btn:hover{border-color:var(--accent);color:var(--text)}
.dlg-btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.dlg-btn.primary{background:var(--accent);border-color:var(--accent);color:#1a1208}
html[data-theme="paper"] .dlg-btn.primary{color:#fff}

/* ============================== GUIDED TOUR ============================== */

/* First-visit coach marks: a spotlight cut out of a full-screen dim (the
   viewport-sized box-shadow trick) plus an explainer card. The veil under
   both swallows taps so the tour owns the screen while it runs. */
.tour-veil{position:fixed;inset:0;z-index:69}
.tour-spot{
  position:fixed;z-index:70;pointer-events:none;border-radius:10px;
  /* The accent ring is inset so it stays whole and evenly shaped even when
     the box is clamped against a screen edge. 200vmax: a 100vmax spread from
     a corner-pinned box leaves the opposite screen corner outside its
     rounded shadow corner (up to ~1.42vmax away). */
  box-shadow:0 0 0 200vmax rgba(0,0,0,.62),inset 0 0 0 2px var(--accent);
  transition:left .22s ease,top .22s ease,width .22s ease,height .22s ease;
}
.tour-card{
  position:fixed;z-index:71;max-width:min(330px,calc(100vw - 24px));
  background:var(--bg-window);border:1px solid var(--border);border-radius:12px;
  box-shadow:0 24px 60px -20px rgba(0,0,0,.7);padding:13px 15px;
}
.tour-step{font-family:var(--mono);font-size:10.5px;color:var(--text-faint);margin-bottom:6px}
.tour-text{font-family:var(--sans);font-size:13.5px;line-height:1.55;color:var(--text)}
.tour-actions{display:flex;align-items:center;gap:10px;margin-top:12px}
.tour-actions .tour-skip{margin-right:auto}

/* ============================== RESPONSIVE ============================== */

/* Window-relative: the chrome reflows to the window's own width, so dragging
   the window narrow triggers the same overlay layout as a small screen. */
@container window (max-width:840px){

  /* Sidebar floats over the content instead of pushing it. */
  .sidebar{position:absolute;left:48px;top:38px;bottom:25px;z-index:20;box-shadow:14px 0 40px -10px rgba(0,0,0,.5)}
  .prose{padding:34px 22px 80px}
  .titlebar .who .path{display:none}
}

/* Even narrower: drop the segmented control and copy button. */
@container window (max-width:560px){
  .seg{display:none}
  .srccopy{display:none}
  .statusbar .si.opt{display:none}
}

/* Real small screens: the window fills the viewport edge-to-edge, no chrome
   or resize handle. (Container queries above still drive the inner layout.) */
@media(max-width:840px){
  .stage{padding:0}
  .window{
    width:100%;height:100%;max-width:none;max-height:none;min-width:0;min-height:0;
    border-radius:0;border:none;
  }

  /* No free-floating window on mobile, so drop the resize grips and neutralize
     the green "maximize" dot (the window already fills the screen). Close (red)
     and minimize (yellow) stay tappable so the window can be dismissed.
     The desktop icon layer stays visible: the launcher is the same draggable
     grid icon here as on desktop, so it is intentionally NOT hidden. */
  .win-handle{display:none}
  .dots .dot.g{pointer-events:none}

  /* Roomier, finger-sized hit targets for the two live dots without changing
     their drawn size. */
  .dots{gap:16px}
  .dots .dot{position:relative}
  .dots .dot::after{content:"";position:absolute;inset:-7px}

  /* Window-kind apps go full-screen too (one at a time on mobile); inline
     drag/resize geometry is overridden and the resize grips are dropped.
     Dialog-kind apps are the exception: they keep the floating, centered,
     content-sized desktop look (rule below). */
  .window.app:not(.dialog){
    position:fixed;inset:0;
    left:0!important;top:0!important;width:100%!important;height:100%!important;
    /* Same dvh treatment as .stage: keep the window's bottom edge (status bar)
       above the browser's dynamic toolbar. */
    height:100dvh!important;
    max-width:none!important;max-height:none!important;min-width:0;
    border-radius:0;border:none;
  }
  .window.app .win-handle{display:none}

  /* Dialogs are modal on mobile: a viewport-sized shadow dims everything
     behind the dialog, and everything behind it goes inert, so the dialog
     has to be closed before the desktop or another launcher can be used. */
  .window.app.dialog{
    max-width:calc(100% - 28px);box-shadow:0 0 0 200vmax rgba(0,0,0,.5);
    /* Restore the desktop window look that the edge-to-edge rules above strip. */
    border-radius:var(--r);border:1px solid var(--border);
  }
  /* .desk-icon must be listed too: it sets pointer-events:auto to stay
     clickable inside the inert .desktop layer, which would win over the
     none inherited from .desktop alone. */
  body:has(.window.app.dialog:not(.hidden)) :is(.desktop,.desk-icon,.window:not(.dialog)){pointer-events:none}

  /* Mobile-only: replays the guided tour. */
  #btn-tour{display:grid}
}

/* Respect reduced-motion: kill the entrance animations. */
@media(prefers-reduced-motion:reduce){
  .window,.node,.prose>*,.source .row,.desk-icon{animation:none!important}
  .tabovf .chev{transition:none}
  .tour-spot{transition:none}
}
