/* ============================================================
   joekane.org — IDE portfolio · shared shell
   GitHub-dark-flavored editor. Mono throughout.
   ============================================================ */

:root {
  --bg:      #0d1117;   /* editor canvas */
  --panel:   #010409;   /* title + tab bar */
  --side:    #0b0f15;   /* explorer */
  --activity:#080b10;   /* activity bar */
  --line:    #1c2433;   /* borders */
  --line2:   #283042;
  --txt:     #c9d1d9;
  --mut:     #8b949e;
  --faint:   #4b5563;
  --gutter:  #3b434f;

  /* syntax */
  --com:  #6a7681;
  --key:  #ff7b72;
  --fn:   #d2a8ff;
  --str:  #a5d6ff;
  --num:  #79c0ff;
  --prop: #79c0ff;
  --tag:  #7ee787;
  --pun:  #8b949e;

  /* status / semantic */
  --accent:  #2f81f7;
  --accent2: #58a6ff;
  --green:   #3fb950;
  --amber:   #d29922;
  --red:     #f85149;

  --gut-w: 60px;
  --side-w: 244px;
  --act-w: 52px;
  --mono: 'JetBrains Mono', 'IBM Plex Mono', ui-monospace, monospace;
  --ease: cubic-bezier(.22,.61,.36,1);
}

/* theme overrides applied by tweaks */
html[data-theme="dim"]  { --bg:#161b22; --side:#10151c; --panel:#0d1117; --activity:#0d1117; --line:#222a35; }
html[data-theme="paper"]{
  --bg:#f6f3ec; --panel:#e9e4d8; --side:#efeade; --activity:#e4dece; --line:#d6cfbe; --line2:#cabfa8;
  --txt:#1f2328; --mut:#6b665c; --faint:#9a948a; --gutter:#b3ab9b;
  --com:#8a857a; --key:#cf222e; --fn:#8250df; --str:#0a7c5a; --num:#0550ae; --prop:#0550ae; --tag:#116329; --pun:#6b665c;
  --accent:#bc4a2d; --accent2:#9a3a22;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--panel);
  color: var(--txt);
  font-family: var(--mono);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
::selection { background: color-mix(in oklch, var(--accent) 38%, transparent); }
a { color: inherit; text-decoration: none; }

/* ---------- App shell ---------- */
.app {
  height: 100vh; height: 100dvh;
  display: grid;
  grid-template-rows: 36px 40px 1fr 26px;
  grid-template-columns: var(--act-w) var(--side-w) 1fr;
  grid-template-areas:
    "title title title"
    "act   tabs  tabs"
    "act   side  editor"
    "status status status";
  background: var(--panel);
}

/* title bar */
.titlebar {
  grid-area: title;
  display: flex; align-items: center; gap: 14px;
  padding: 0 14px;
  border-bottom: 1px solid var(--line);
  font-size: 12px; color: var(--mut);
}
.lights { display: flex; gap: 8px; }
.lights i { width: 12px; height: 12px; border-radius: 50%; display: block; }
.lights .r { background: #ff5f57; }
.lights .y { background: #febc2e; }
.lights .g { background: #28c840; }
.titlebar .crumb { margin-left: 6px; letter-spacing: .02em; }
.titlebar .crumb b { color: var(--txt); font-weight: 500; }
.titlebar .right { margin-left: auto; display: flex; gap: 16px; align-items: center; }
.titlebar .right span { opacity: .8; }
.kbd-hint { border: 1px solid var(--line2); border-radius: 5px; padding: 2px 8px; font-size: 11px; color: var(--mut); cursor: pointer; transition: .15s; }
.kbd-hint:hover { color: var(--txt); border-color: var(--accent); }

/* activity bar */
.activity {
  grid-area: act;
  background: var(--activity);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column; align-items: center;
  padding: 12px 0; gap: 4px;
}
.activity .ico {
  width: 40px; height: 40px; display: grid; place-items: center;
  color: var(--faint); cursor: pointer; border-left: 2px solid transparent;
  transition: color .15s;
}
.activity .ico:hover { color: var(--mut); }
.activity .ico.on { color: var(--txt); border-left-color: var(--accent); }
.activity .ico svg { width: 22px; height: 22px; }
.activity .spacer { flex: 1; }

/* tab bar */
.tabbar {
  grid-area: tabs;
  display: flex; align-items: stretch;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  overflow-x: auto; scrollbar-width: none;
}
.tabbar::-webkit-scrollbar { display: none; }
.tab {
  display: flex; align-items: center; gap: 8px;
  padding: 0 14px; font-size: 12.5px; color: var(--mut);
  border-right: 1px solid var(--line); white-space: nowrap;
  cursor: pointer; transition: background .15s, color .15s; position: relative;
}
.tab:hover { color: var(--txt); }
.tab.on { background: var(--bg); color: var(--txt); }
.tab.on::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: var(--accent); }
.tab .ext { color: var(--accent2); }
.tab .close { opacity: .4; font-size: 14px; }
.tab:hover .close { opacity: .9; }

/* file-type glyph badges */
.fkind {
  display: inline-grid; place-items: center;
  width: 20px; height: 16px; border-radius: 3px;
  font-size: 9px; font-weight: 700; letter-spacing: .02em;
  color: #0d1117; flex: none;
}
.fkind.fk-ts   { background: #58a6ff; }
.fkind.fk-json { background: #d29922; }
.fkind.fk-md   { background: #79c0ff; }
.fkind.fk-x    { background: #8b949e; }
.exp-file .fi .fkind { width: 22px; height: 17px; font-size: 9.5px; }
.hide-sm { }

/* explorer */
.explorer {
  grid-area: side;
  background: var(--side);
  border-right: 1px solid var(--line);
  overflow-y: auto; padding: 10px 0;
  font-size: 13px;
}
.explorer::-webkit-scrollbar { width: 10px; }
.explorer::-webkit-scrollbar-thumb { background: var(--line2); border-radius: 6px; }
.exp-group {
  display: flex; align-items: center; gap: 6px;
  padding: 6px 12px 6px 10px; color: var(--mut);
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  cursor: default; user-select: none;
}
.exp-group .chev { transition: transform .2s; }
.exp-file {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 12px 5px 26px; color: var(--mut);
  cursor: pointer; transition: background .12s, color .12s; position: relative;
}
.exp-file:hover { background: rgba(255,255,255,.035); color: var(--txt); }
.exp-file.sel { background: color-mix(in oklch, var(--accent) 16%, transparent); color: var(--txt); }
.exp-file.sel::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; background: var(--accent); }
.exp-file .fi { width: 15px; text-align: center; opacity: .9; flex: none; }
.exp-file .badge { margin-left: auto; font-size: 10px; color: var(--green); }
.exp-file.ext-link .fi { color: var(--accent2); }

/* ---------- Editor ---------- */
.editor {
  grid-area: editor;
  background: var(--bg);
  overflow-y: auto; overflow-x: hidden;
  position: relative;
  scroll-behavior: smooth;
}
.editor::-webkit-scrollbar { width: 14px; }
.editor::-webkit-scrollbar-thumb { background: var(--line2); border: 4px solid var(--bg); border-radius: 8px; }
.editor::-webkit-scrollbar-thumb:hover { background: #39414f; }

/* gutter + content wrapper */
.doc { display: grid; grid-template-columns: var(--gut-w) 1fr; min-height: 100%; }
.gutter {
  position: relative; text-align: right;
  color: var(--gutter); font-size: 13px; line-height: 28px;
  padding-top: 28px; user-select: none;
  border-right: 1px solid color-mix(in oklch, var(--line) 60%, transparent);
}
.gutter b { display: block; padding-right: 16px; font-weight: 400; }
.content { padding: 28px 0 120px; min-width: 0; }

/* code lines / generic mono helpers */
.codeline { padding: 0 40px; line-height: 28px; white-space: pre-wrap; }
.com { color: var(--com); font-style: italic; }
.key { color: var(--key); }
.fn  { color: var(--fn); }
.str { color: var(--str); }
.num { color: var(--num); }
.prop{ color: var(--prop); }
.tag { color: var(--tag); }
.pun { color: var(--pun); }
.mut { color: var(--mut); }

/* caret */
.caret { display:inline-block; width:8px; height:18px; background:var(--accent2); vertical-align:-3px; animation:blink 1.05s step-end infinite; }
@keyframes blink { 50% { opacity:0; } }

/* ---------- Section building blocks ---------- */
.block { padding: 0 40px; max-width: 980px; }
.lead-com { color: var(--com); font-style: italic; font-size: 14px; line-height: 28px; }
h1.big { font-size: clamp(40px, 6vw, 76px); font-weight: 800; letter-spacing: -.03em; line-height: .98; margin: 6px 0 0; color: var(--txt); }
.role { color: var(--str); font-size: clamp(16px,2vw,21px); margin: 18px 0 0; }
.tagline { color: var(--mut); font-size: 16px; max-width: 60ch; margin: 22px 0 0; line-height: 1.75; }

.btns { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }
.btn {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 11px 18px; font-size: 13.5px; font-family: var(--mono);
  border: 1px solid var(--line2); border-radius: 8px;
  color: var(--txt); background: rgba(255,255,255,.02);
  cursor: pointer; transition: .18s var(--ease);
}
.btn:hover { border-color: var(--accent); background: color-mix(in oklch, var(--accent) 12%, transparent); transform: translateY(-1px); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primary:hover { background: var(--accent2); border-color: var(--accent2); }
.btn .arr { transition: transform .18s var(--ease); }
.btn:hover .arr { transform: translateX(3px); }

/* section header used across pages */
.sec-head { margin: 70px 0 26px; }
.sec-head .ln { color: var(--com); font-style: italic; font-size: 13px; }
.sec-head h2 { font-size: clamp(24px,3vw,34px); font-weight: 700; letter-spacing: -.02em; margin: 6px 0 0; }
.sec-head h2 .pun { font-weight: 400; }

/* reveal-on-scroll */
[data-reveal] { opacity: 0; transform: translateY(18px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
[data-reveal].in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { [data-reveal] { opacity: 1 !important; transform: none !important; transition: none; } }

/* ---------- Status bar ---------- */
.statusbar {
  grid-area: status;
  background: var(--accent);
  color: #fff; display: flex; align-items: center; gap: 0;
  font-size: 11.5px; padding: 0;
}
.statusbar .seg { display: flex; align-items: center; gap: 6px; padding: 0 10px; height: 100%; }
.statusbar .seg.click { cursor: pointer; transition: background .15s; }
.statusbar .seg.click:hover { background: rgba(255,255,255,.16); }
.statusbar .grow { margin-left: auto; }
.statusbar svg { width: 13px; height: 13px; }

/* ---------- Command palette ---------- */
.palette-scrim {
  position: fixed; inset: 0; background: rgba(1,4,9,.55);
  display: none; align-items: flex-start; justify-content: center;
  padding-top: 12vh; z-index: 200; backdrop-filter: blur(2px);
}
.palette-scrim.open { display: flex; }
.palette {
  width: min(620px, 92vw); background: var(--side);
  border: 1px solid var(--line2); border-radius: 12px;
  box-shadow: 0 24px 70px rgba(0,0,0,.6); overflow: hidden;
  animation: popin .18s var(--ease);
}
@keyframes popin { from { opacity: 0; transform: translateY(-8px) scale(.99); } }
.palette input {
  width: 100%; border: 0; background: transparent; color: var(--txt);
  font-family: var(--mono); font-size: 15px; padding: 16px 18px;
  border-bottom: 1px solid var(--line); outline: none;
}
.palette .results { max-height: 320px; overflow-y: auto; padding: 6px; }
.palette .pr {
  display: flex; align-items: center; gap: 12px; padding: 11px 12px;
  border-radius: 8px; cursor: pointer; color: var(--mut); font-size: 13.5px;
}
.palette .pr .fi { width: 16px; text-align: center; }
.palette .pr .desc { margin-left: auto; font-size: 11.5px; color: var(--faint); }
.palette .pr.active, .palette .pr:hover { background: color-mix(in oklch, var(--accent) 18%, transparent); color: var(--txt); }

/* ---------- Tweaks panel (vanilla) ---------- */
.tw-toggle { display: none; }
#tweaks {
  position: fixed; right: 16px; bottom: 40px; z-index: 180;
  width: 250px; background: var(--side); border: 1px solid var(--line2);
  border-radius: 12px; box-shadow: 0 18px 50px rgba(0,0,0,.5);
  font-size: 12.5px; overflow: hidden; display: none;
}
#tweaks.show { display: block; }
#tweaks .tw-hd { display: flex; align-items: center; justify-content: space-between; padding: 11px 14px; border-bottom: 1px solid var(--line); color: var(--txt); font-weight: 500; }
#tweaks .tw-hd .x { cursor: pointer; color: var(--mut); }
#tweaks .tw-body { padding: 12px 14px; display: flex; flex-direction: column; gap: 14px; }
#tweaks .tw-row .lbl { color: var(--mut); margin-bottom: 8px; letter-spacing: .04em; }
#tweaks .seg-ctl { display: flex; gap: 6px; }
#tweaks .seg-ctl button { flex: 1; padding: 7px 4px; border: 1px solid var(--line2); background: transparent; color: var(--mut); border-radius: 7px; font-family: var(--mono); font-size: 11.5px; cursor: pointer; transition: .15s; }
#tweaks .seg-ctl button.on { background: var(--accent); border-color: var(--accent); color: #fff; }
#tweaks .swatches { display: flex; gap: 8px; }
#tweaks .swatches button { width: 30px; height: 30px; border-radius: 8px; border: 2px solid transparent; cursor: pointer; }
#tweaks .swatches button.on { border-color: var(--txt); }

/* ---------- Project / card primitives ---------- */
.card {
  border: 1px solid var(--line); border-radius: 12px;
  background: color-mix(in oklch, var(--bg) 70%, #000 6%);
  overflow: hidden; transition: border-color .2s, transform .2s;
}
.card:hover { border-color: var(--line2); }

/* mobile — collapse the IDE chrome to a phone-friendly shell:
   the tab bar becomes the nav, the activity rail + file tree fold
   away (every destination is still reachable from the tabs, the
   ⌘K palette and the links page), and the editor goes full width. */
@media (max-width: 860px) {
  html, body { overflow-x: hidden; }
  body { overflow-y: auto; -webkit-tap-highlight-color: transparent; }
  .app {
    grid-template-rows: 36px 40px 1fr 26px;
    grid-template-columns: 1fr;
    grid-template-areas: "title" "tabs" "editor" "status";
    height: auto; min-height: 100dvh;
  }

  /* hide desktop-only chrome: activity rail, file tree, and the
     informational title/status labels carrying .hide-sm */
  .activity,
  .explorer,
  .hide-sm { display: none !important; }

  /* title bar: compact, and never overflows its row */
  .titlebar { gap: 10px; padding: 0 12px; }
  .titlebar .crumb { margin-left: 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .titlebar .right { gap: 10px; }

  /* tab bar is the primary nav here — keep it pinned while scrolling */
  .tabbar { position: sticky; top: 0; z-index: 50; }
  .tab { padding: 0 16px; font-size: 13px; }

  /* editor spans full width, no line-number gutter */
  .editor { overflow: visible; }
  .doc { grid-template-columns: 0 1fr; }
  .gutter { display: none; }
  .content { padding: 22px 0 80px; }
  .content, .block { padding-left: 20px; padding-right: 20px; }
  .codeline { padding: 0 20px; }

  /* status bar: roomier taps for the segments that remain */
  .statusbar .seg { padding: 0 12px; }

  #tweaks { right: 10px; left: 10px; width: auto; }
}

/* ============================================================
   Page transitions — a quick crossfade between "files" so
   navigating doesn't hard-cut. Driven from shell.js as a plain
   opacity fade: the open document fades out, we navigate, the
   next one fades in. Opacity-only and *sequential* (the two
   pages never overlap), so it can't jump regardless of scroll
   position or differing page heights. Honours reduced motion.
   ============================================================ */

/* Carry the canvas colour on <html> too, so a swap never flashes
   white in the moment between documents. */
html { background: var(--panel); }

@media (prefers-reduced-motion: no-preference) {
  .jk-anim .doc            { animation: jk-fade-in 200ms var(--ease) both; }
  .jk-anim.jk-leaving .doc { animation: jk-fade-out 130ms var(--ease) both; }
}

@keyframes jk-fade-in  { from { opacity: 0; } }
@keyframes jk-fade-out { to   { opacity: 0; } }
