/* overlays.css
   Everything that sits above the page: the tl;dr dialog, the edge tabs and the deep-dive panel they open,
   and the ask-me-anything terminal. The dialogs build on the terminal-window primitive in base.css.
   Edge tabs: small labelled tabs on portrait and small screens; fans of page covers on landscape screens
   from 1000x600 (keep that query in step with Site.COVERS in assets/js/boot.js).
   Behaviour: tldr.js, deep-pages.js, reading.js (tucking the fans), chat.js.
*/

/* ==== tl;dr dialog ==== */

/* tl;dr: the short version of a research project, in a terminal window */
.tldr-backdrop {
  position: fixed; inset: 0; z-index: 220; display: flex; align-items: center; justify-content: center;
  padding: max(16px, env(safe-area-inset-top)) 16px max(16px, env(safe-area-inset-bottom)); background: rgba(0, 4, 1, 0.72); backdrop-filter: blur(3px);
}
.tldr-backdrop[hidden] { display: none; }
.tldr .term-bar { flex: none; }   /* the bar never scrolls away; only the body scrolls */
.tldr {
  width: min(780px, 100%); max-height: min(86vh, 900px); max-height: min(86dvh, 900px);   /* dvh: the space actually visible, below a phone's address bar */ display: flex; flex-direction: column; overflow: hidden;
  background: var(--panel-bg); border: 1px solid var(--border-bright); border-radius: 8px;
  box-shadow: 0 0 0 1px rgba(var(--acc-rgb),0.06), 0 24px 70px rgba(0,0,0,0.8), 0 0 40px rgba(var(--acc-rgb),0.12);
  animation: term-in 0.2s ease-out;
}
.tldr-body { overflow-y: auto; padding: 18px 22px 22px; overscroll-behavior: contain; }
.tldr-body h3 { font-family: var(--mono); font-size: 1.05rem; margin-bottom: 4px; }
.tldr-body h3::before { content: '$ '; color: var(--green); }
.tldr-q { color: var(--text); font-size: 1rem; line-height: 1.55; margin: 10px 0 4px; }
.tldr-body h4 {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--green); margin: 18px 0 6px;
}
.tldr-body h4::before { content: '## '; opacity: 0.6; }
.tldr-body p, .tldr-body li { color: var(--text-body); font-size: 0.9rem; line-height: 1.6; }
.tldr-body ul { list-style: none; padding: 0; }
.tldr-body li { position: relative; padding-left: 18px; margin-bottom: 6px; }
.tldr-body li::before { content: '▸'; position: absolute; left: 0; color: var(--green); }
.tldr-body b { color: var(--text); font-weight: 600; }
.tldr-body figure { margin: 6px 0 4px; }
.tldr-body figure { margin: 10px 0 6px; }
.tldr-body .yt { position: relative; aspect-ratio: 16 / 9; border-radius: 6px; overflow: hidden; border: 1px solid var(--border); background: #000; }
.tldr-body .yt.tall { max-height: 70vh; width: auto; margin: 0 auto; }
.tldr-body .yt iframe, .tldr-body .yt video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; object-fit: contain; }
.tldr-body figure img { display: block; max-width: 100%; max-height: 480px; width: auto; height: auto; margin: 0 auto; border-radius: 6px; }
.tldr-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.tldr-row img { width: 100%; max-height: none; }
/* an app screen in a phone frame, beside a diagram */
.tldr-app { display: grid; grid-template-columns: 170px 1fr; gap: 16px; align-items: center; }
.tldr-app img:first-child {
  width: 100%; max-height: none; border-radius: 22px; padding: 10px 6px 18px;
  background: #111613; border: 2px solid #2a3a2e; box-shadow: 0 0 24px rgba(var(--acc-rgb),0.12);
}
.tldr-app img:last-child { width: 100%; max-height: none; }
@media (max-width: 640px) { .tldr-app { grid-template-columns: 1fr; gap: 14px; } .tldr-app img:first-child { width: 160px; margin: 0 auto; } }
.tldr-body figcaption { font-family: var(--mono); font-size: 0.7rem; color: var(--text-muted); margin-top: 6px; }
.tldr-body table { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 0.78rem; }
.tldr-body td { padding: 5px 8px; border-bottom: 1px solid var(--border); color: var(--text-muted); }
.tldr-body td:last-child { text-align: right; color: var(--text); white-space: nowrap; }
.tldr-body tr.good td:last-child { color: var(--green); }
.tldr-body tr.bad td:last-child { color: #ff8a80; }
.tldr-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px; }
.tldr-links a {
  font-family: var(--mono); font-size: 0.8rem; color: var(--green); text-decoration: none;
  border: 1px solid var(--border-bright); border-radius: 6px; padding: 8px 14px; background: rgba(var(--acc-rgb),0.04);
}
.tldr-links a:hover { border-color: var(--green); background: rgba(var(--acc-rgb),0.1); }
@media (max-width: 640px) {
  .tldr-backdrop { padding: 0; align-items: flex-end; }
  .tldr { max-height: 90vh; max-height: 90dvh; border-radius: 10px 10px 0 0; }   /* dvh: never taller than the visible area */
  .tldr-body { padding: 16px; }
}


/* ==== Edge tabs and deep-dive panel ==== */

/* 2) reading mode: scrolling down tucks both fans to a sliver; scrolling up brings them back. The hologram stays as it is. */
@media (min-width: 1000px) and (min-aspect-ratio: 1/1) and (min-height: 600px) {
  .edge-tabs { transition: translate 0.45s cubic-bezier(.2, .8, .2, 1), opacity 0.35s; }
  .fans-tucked .edge-tabs:not(.left) { translate: calc(var(--tw) * 0.36) 0; opacity: 0.6; }
  .fans-tucked .edge-tabs.left { translate: calc(var(--tw) * -0.36) 0; opacity: 0.6; }
  .fans-tucked .edge-tabs:hover, .fans-tucked .edge-tabs:focus-within { translate: 0 0; opacity: 1; }
}
/* phones, tablets and small laptop windows: same reading mode; the tabs slide off to a sliver while reading down and return on the way up */
@media not all and (min-width: 1000px) and (min-aspect-ratio: 1/1) and (min-height: 600px) {
  /* coming back is a little spring (the pop); going away is a plain glide */
  .edge-tabs { transition: translate 0.55s cubic-bezier(.34, 1.56, .64, 1), opacity 0.25s ease-out; }
  .fans-tucked .edge-tabs { transition: translate 0.4s cubic-bezier(.4, 0, .2, 1), opacity 0.3s; }
  .fans-tucked .edge-tabs:not(.left) { translate: calc(100% - 6px) 0; opacity: 0.5; }
  .fans-tucked .edge-tabs.left { translate: calc(-100% + 6px) 0; opacity: 0.5; }
}

/* Deep pages: folder tabs stick out of the right edge; one click swings the page in,
   hinged on that edge like a door opening towards you. Each page is also a real URL. */
.edge-tabs { position: fixed; right: 0; top: 50%; transform: translateY(-50%); z-index: 70;
  display: flex; flex-direction: column; gap: 10px; align-items: flex-end; }
.edge-tab { writing-mode: vertical-rl; transform: rotate(180deg); font-family: var(--mono); font-size: 0.74rem;
  letter-spacing: 0.08em; color: var(--green); text-decoration: none; padding: 16px 9px 16px 8px;
  background: rgba(5, 12, 7, 0.92); border: 1px solid var(--border-bright); border-left: 0; border-radius: 8px 0 0 8px;
  box-shadow: -4px 0 18px rgba(var(--acc-rgb), 0.08); transition: padding 0.25s, background 0.25s, box-shadow 0.25s; }
.edge-tab { border-left: 1px solid var(--border-bright); border-right: 0; border-radius: 0 8px 8px 0; }
.edge-tab::before { content: '~/'; opacity: 0.55; }
.edge-tab:hover, .edge-tab:focus-visible { padding-bottom: 26px; background: rgba(var(--acc-rgb), 0.1); box-shadow: -6px 0 24px rgba(var(--acc-rgb), 0.22); outline: none; }
.deep-panel { position: fixed; inset: 0; z-index: 210; overflow-y: auto; overscroll-behavior: contain; background: var(--bg);
  transform-origin: right center; perspective: 1600px; }
.deep-panel[hidden] { display: none; }
.deep-panel.swing-in { animation: deep-swing-in 0.62s cubic-bezier(.2, .8, .2, 1) both; }
.deep-panel.swing-out { animation: deep-swing-out 0.45s cubic-bezier(.5, 0, .75, .2) both; }
@keyframes deep-swing-in { from { transform: perspective(1600px) rotateY(-78deg); opacity: 0.2; } to { transform: perspective(1600px) rotateY(0); opacity: 1; } }
@keyframes deep-swing-out { from { transform: perspective(1600px) rotateY(0); opacity: 1; } to { transform: perspective(1600px) rotateY(-78deg); opacity: 0; } }
.deep-close { position: sticky; top: 0; z-index: 2; display: block; width: 100%; text-align: left; cursor: pointer;
  background: rgba(1, 2, 3, 0.86); backdrop-filter: blur(10px); border: 0; border-bottom: 1px solid var(--border);
  padding: 14px 24px; font-family: var(--mono); font-size: 0.85rem; color: var(--text-muted); }
.deep-close:hover { color: var(--green); }
.deep-close:focus { outline: none; }   /* no system-coloured ring when the panel opens */
.deep-close:focus-visible { color: var(--green); box-shadow: inset 3px 0 0 var(--green); }
/* Laptop: the tabs are a loose fan of page covers (real screenshots), tilted and overlapping
   at the right edge. Hover straightens one, lifts it to the top, lights it and slides it in
   about a centimetre; a click grows it from there into the full page.
   Only from 1181px, where the left fan shows too; narrower windows get the small tabs on both sides. */
@media (min-width: 1000px) and (min-aspect-ratio: 1/1) and (min-height: 600px) {
  /* covers scale with the window, like the hologram: bigger on big screens, smaller on small */
  /* each fan fills the top 76% of the window, leaving the bottom corners to the satellite: the covers grow with the window's height
     (a stack of four is about 2.13 covers tall), up to a quarter of its width, and whatever height is left over spreads them apart */
  .edge-tabs { --tw: clamp(150px, min(25vw, (76vh - 76px) / 2.13), 380px); --peek: 0.47; gap: 0; width: calc(var(--tw) * var(--peek)); align-items: flex-start;
    top: 70px; height: calc(76vh - 70px); justify-content: space-between; transform: none; }
  .edge-tab { writing-mode: horizontal-tb; flex: none; position: relative; width: var(--tw); height: calc(var(--tw) * 0.652); padding: 0;
    margin: calc(var(--tw) * -0.06) 0; transform: translateX(var(--dx, 0)) rotate(var(--tilt, -6deg)); overflow: hidden;
    border: 6px solid #0b0f0d; border-radius: 16px; outline: 1px solid var(--border-bright); outline-offset: -1px;
    background: #050a07 var(--shot) left top / cover no-repeat;
    box-shadow: -14px 12px 34px rgba(0, 0, 0, 0.7); filter: brightness(0.66) saturate(0.75);
    transition: transform 0.36s cubic-bezier(.2, .8, .2, 1), filter 0.25s, box-shadow 0.25s, outline-color 0.25s; }
  .edge-tab:nth-child(1) { --tilt: -7deg; --dx: 6px; z-index: 1; }
  .edge-tab:nth-child(2) { --tilt: 5deg; --dx: 2px; z-index: 2; }  /* the longest label gets the most room */
  .edge-tab:nth-child(3) { --tilt: -4deg; --dx: 18px; z-index: 3; }
  .edge-tab:nth-child(4) { --tilt: 6deg; --dx: 14px; z-index: 4; }
  .edge-tab::before { content: none; }
  .edge-tab:hover, .edge-tab:focus-visible { z-index: 9; transform: translateX(calc(var(--tw) * -0.14)) rotate(0) scale(1.04); filter: none; padding: 0;
    background: #050a07 var(--shot) left top / cover no-repeat; outline: 1px solid var(--green); outline-offset: -1px;
    box-shadow: -18px 14px 40px rgba(0, 0, 0, 0.75), -6px 0 34px rgba(var(--acc-rgb), 0.3); }
  .et-label { position: absolute; left: 10px; top: 8px; writing-mode: horizontal-tb; transform: none;
    font-size: clamp(0.42rem, calc(var(--tw) * 0.0335), 0.56rem); letter-spacing: 0.05em; text-transform: uppercase; color: var(--green);  /* shrinks with the cover on narrower windows */
    background: rgba(1, 4, 2, 0.85); border: 1px solid var(--border-bright); border-radius: 999px; padding: 3px 8px; white-space: nowrap; }
  .edge-tab:hover .et-label { border-color: var(--green); text-shadow: 0 0 8px rgba(var(--acc-rgb), 0.7); }
  .et-label::before { content: '~/'; opacity: 0.55; text-transform: none; }
}
/* landscape tablets and small laptop windows: the same covers, showing a little less of each so they keep clear of the text */
@media (min-width: 1000px) and (max-width: 1180px) and (min-aspect-ratio: 1/1) and (min-height: 600px) {
  .edge-tabs { --peek: 0.44; }
  .et-label { letter-spacing: 0; padding: 3px 6px; left: 8px; }
  .et-label::before { content: none; }   /* no ~/ here, so the whole label fits on the narrower strip */
  .nav-left .ask-hint { left: 34px; }   /* clear of the left fan */
}
@media (max-width: 640px) { .edge-tab { font-size: 0.66rem; padding: 12px 6px 12px 5px; } .edge-tabs { top: 42%; } }
/* Profiles: the same fan mirrored on the left edge, opening GitHub and LinkedIn in a new tab.
   Wide screens only, so it never crowds the terminal hint under the nav. */
.edge-tabs.left { display: none; }
/* each profile tab carries its logo: green like the rest of the page, the brand's own colour on hover */
.et-logo { width: 18px; height: 18px; fill: currentColor; display: block; flex: none; transition: fill 0.2s; }
.edge-tabs.left .edge-tab:hover .et-logo, .edge-tabs.left .edge-tab:focus-visible .et-logo, .edge-tabs.left .edge-tab:active .et-logo { fill: var(--brand, currentColor); }
/* phones, tablets and small laptop windows: the profiles are labelled tabs on the left edge, the same shape as the
   deep-dive tabs on the right (mirrored), in place of the two hero buttons */
@media not all and (min-width: 1000px) and (min-aspect-ratio: 1/1) and (min-height: 600px) {
  .edge-tabs.left { display: flex; right: auto; left: 0; align-items: flex-start; }
  .edge-tabs.left .edge-tab { border-left: 0; border-right: 1px solid var(--border-bright); border-radius: 8px 0 0 8px;
    box-shadow: 4px 0 18px rgba(var(--acc-rgb), 0.08); }
  .edge-tabs.left .edge-tab::before { content: none; }   /* other sites, so no ~/ */
  .edge-tabs.left .edge-tab:hover, .edge-tabs.left .edge-tab:focus-visible { box-shadow: 6px 0 24px rgba(var(--acc-rgb), 0.22); }
  .hero-profile { display: none; }
  /* both sides: the icon sits at the top of the tab, upright, with the label reading up beneath it */
  .edge-tab .et-label { display: inline-flex; align-items: center; gap: 7px; }
  .edge-tab .et-logo, .edge-tab .et-ico { display: block; order: 2; width: 14px; height: 14px; transform: rotate(180deg); }
}
@media (max-width: 640px) { .edge-tab .et-logo, .edge-tab .et-ico { width: 12px; height: 12px; } }
@media (min-width: 1000px) and (min-aspect-ratio: 1/1) and (min-height: 600px) {
  /* same height and reach as the right-hand fan, mirrored; only the stacking differs */
  .edge-tabs.left { display: flex; right: auto; left: 0; align-items: flex-end; }
  /* the covers replace the two profile buttons in the hero; narrower screens keep the buttons */
  .hero-profile { display: none; }
  /* the cover hangs off the left edge, so its picture starts where the visible part does */
  .edge-tabs.left .edge-tab { background-position: calc(var(--tw) * (1.04 - var(--peek))) 0; box-shadow: 14px 12px 34px rgba(0, 0, 0, 0.7);
    transition: transform 0.36s cubic-bezier(.2, .8, .2, 1), filter 0.25s, box-shadow 0.25s, outline-color 0.25s, background-position 0.36s cubic-bezier(.2, .8, .2, 1); }
  /* the right fan piles upward (last cover on top); this one piles downward (first cover on top) */
  .edge-tabs.left .edge-tab:nth-child(1) { --tilt: 7deg; --dx: -6px; z-index: 4; }
  .edge-tabs.left .edge-tab:nth-child(2) { --tilt: -5deg; --dx: -18px; z-index: 3; }
  .edge-tabs.left .edge-tab:nth-child(3) { --tilt: 4deg; --dx: -2px; z-index: 2; }
  .edge-tabs.left .edge-tab:nth-child(4) { --tilt: -6deg; --dx: -14px; z-index: 1; }
  .edge-tabs.left .et-label { display: inline-flex; align-items: center; gap: 6px; }
  .edge-tabs.left .et-logo { width: 11px; height: 11px; }
  /* these go to other sites, so no ~/ path prefix; it also keeps the pill inside the visible part of the cover */
  .edge-tabs.left .et-label::before { content: none; }
  .edge-tabs.left .edge-tab:hover, .edge-tabs.left .edge-tab:focus-visible { transform: translateX(calc(var(--tw) * 0.14)) rotate(0) scale(1.04);
    background-position: calc(var(--tw) * (0.89 - var(--peek))) 0; box-shadow: 18px 14px 40px rgba(0, 0, 0, 0.75), 6px 0 34px rgba(var(--acc-rgb), 0.3); }
  /* this fan piles downward, so each cover shows its bottom strip: the label sits there */
  .edge-tabs.left .et-label { left: auto; right: 10px; top: auto; bottom: 8px; }
}
/* the deep-dive tabs get a line icon, shown only on the small labelled tabs */
.et-ico { display: none; width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
@media (prefers-reduced-motion: reduce) { .deep-panel.swing-in, .deep-panel.swing-out { animation-duration: 0.01s; } }


/* ==== Ask-me-anything terminal ==== */

/* Ask-me-anything terminal: opens from the blinking prompt in the nav. */
/* hangs under the prompt like a tab; hidden once the visitor scrolls on */
.ask-hint {
  position: absolute; top: calc(100% + 14px); left: -2px;
  font-family: var(--mono); font-size: 0.72rem; color: var(--green);
  background: rgba(1, 8, 3, 0.92); border: 1px dashed var(--green-dim); border-radius: 4px;
  padding: 5px 10px; cursor: pointer; white-space: nowrap;
  animation: ask-pulse 2.4s ease-in-out 4;
  transition: opacity 0.3s, transform 0.3s;
}
.ask-hint::before {
  content: ''; position: absolute; top: -6px; left: 18px; width: 10px; height: 10px;
  background: inherit; border-left: 1px dashed var(--green-dim); border-top: 1px dashed var(--green-dim);
  transform: rotate(45deg);
}
.ask-hint.gone { opacity: 0; transform: translateY(-6px); pointer-events: none; }
.ask-hint:hover { border-style: solid; background: rgba(var(--acc-rgb), 0.12); }
.ask-short { display: none; }
@keyframes ask-pulse { 50% { box-shadow: 0 0 12px rgba(var(--acc-rgb), 0.35); } }
.chat {
  position: fixed; right: 24px; bottom: 24px; z-index: 200;
  width: min(440px, calc(100vw - 32px)); height: min(560px, calc(100vh - 110px)); height: min(560px, calc(100dvh - 110px));
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--panel-bg); border: 1px solid var(--border-bright); border-radius: 8px;
  box-shadow: 0 0 0 1px rgba(var(--acc-rgb),0.06), 0 20px 60px rgba(0,0,0,0.7), 0 0 40px rgba(var(--acc-rgb),0.12);
  animation: term-in 0.2s ease-out;
}
.chat[hidden] { display: none; }
.chat-log {
  flex: 1; overflow-y: auto; padding: 14px 16px;
  font-family: var(--mono); font-size: 0.8rem; line-height: 1.6;
  color: var(--text-muted); overscroll-behavior: contain;
}
.chat-log > div { margin-bottom: 10px; white-space: pre-wrap; word-wrap: break-word; }
.chat-log .q { color: var(--text); }
.chat-log .q::before { content: '$ '; color: var(--green); }
.chat-log .sys { color: var(--green-dim); }
.chat-log .err { color: #ff8a80; }
.chat-log .ai::before { content: '\203A  '; color: var(--green); }
.chat-log a { color: var(--green); }
.chat-log code { color: var(--green); }
.chat-log .thinking::after { content: '\2588'; color: var(--green); animation: term-blink 1s steps(1) infinite; }
.chat-form { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--border); background: var(--bg-soft); }
.chat-form label { font-family: var(--mono); font-size: 0.78rem; color: var(--green); white-space: nowrap; }
.chat-form input {
  flex: 1; min-width: 0; background: transparent; border: 0; outline: none; color: var(--text);
  font-family: var(--mono); font-size: 0.82rem; caret-color: var(--green);
}
.chat-foot { padding: 0 14px 8px; background: var(--bg-soft); font-family: var(--mono); font-size: 0.64rem; color: var(--text-muted); opacity: 0.75; }
@media (max-width: 640px) {
  .ask-long { display: none; } .ask-short { display: inline; }
  .chat { right: 0; bottom: 0; width: 100vw; height: 78vh; height: 78dvh; border-radius: 10px 10px 0 0; }
  .chat-form input { font-size: 16px; } /* stops iOS zooming on focus */
}
@media (prefers-reduced-motion: reduce) { .ask-hint, .chat { animation: none; } }
