/*
  HP 48 GX WebAssembly — page-specific styles.

  The shared site chrome — PaperMod :root theme variables, body, a, .nav, .logo,
  #menu, .main, .post-header/.post-title/.post-meta/.post-content and .footer —
  comes from the site-wide stylesheet, linked BEFORE this file in shell.html:
    https://g.autric.net/assets/css/stylesheet.css
  Only the rules below are specific to the emulator page (the calculator canvas,
  the HOME tree panel, the serial controls). They inherit the theme CSS custom
  properties (--radius, --border, --code-bg, --theme, --primary, --secondary,
  --tertiary, --content, --gap ...) from that stylesheet, so keep it linked.
*/
/* Widen the content column for the emulator. PaperMod's reading column
   (--main-width ≈ 720px of content) is too narrow: calculator (~365px) +
   burger toggle (~37px) + HOME panel (300px) + gaps ≈ 735px must share ONE
   row, so at 720px the panel (or toggle) is forced to wrap underneath. This
   page is a single-purpose tool, not an article, so give <main> a wider cap.
   Scoped to this page only (x48ng.css is linked solely here); the top nav and
   the footer live OUTSIDE <main>, so their width is untouched. On real mobile
   the viewport caps the width and the row still wraps to stack vertically. */
.main {
  max-width: 880px;
}
/* Stage is a row: calculator column on the left, then the always-visible
   burger toggle directly to its right (the "hide/show" control lives to the
   right of the HP 48, per spec), then the HOME tree panel. The panel is LAST
   in the flow so that when the row is too wide it is the panel — not the
   toggle — that flex-wraps below the calculator; the toggle stays on the top
   row next to the calc. Same wrap gives the mobile layout (panel underneath).

   This is the OPEN layout: calculator on the left, HOME panel pushed to the
   right (see #tree-panel's margin-inline-start:auto). The burger is pinned to
   the stage's right in BOTH states, taken out of the flow (see #tree-toggle),
   with its top aligned to the top of the HP 48 skin (the canvas). When the
   panel is closed the calculator is centered instead — see
   #stage:has(#tree-panel.hidden).

   --hp-top is the vertical distance from the stage's top to the top of the
   canvas: the stage's own padding-top (0.5rem) plus, inside #calc-col, the
   empty #status line (min-height 1.2em at 0.85rem = 1.02rem) and the column
   gap (0.75rem) that sit above the canvas. The burger uses it to line up with
   the skin, and the panel to clear the burger below it. */
#stage {
  --hp-top: 2.27rem;
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 1rem;
  position: relative;
  padding: 0.5rem 0;
}
/* Panel closed: nothing on the right to balance the calculator, so center it.
   (The burger is already absolute top-right, so it never pulls it off-centre.) */
#stage:has(#tree-panel.hidden) {
  justify-content: center;
}
/* The calculator column keeps the ORIGINAL centered-column layout so the
   canvas-sizing contract below is untouched (canvas is never stretched by
   a flex cross-axis: align-items:center, and min-width:0 lets the column
   shrink without forcing a width onto the canvas). */
#calc-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
}
/* Right-side HOME tree panel. */
#tree-panel {
  flex: 0 0 300px;
  width: 300px;
  max-width: 90vw;
  max-height: calc(100vh - 260px);
  overflow: auto;
  /* With the burger out of the flow, push the panel to the stage's right, and
     start it just below the burger (which sits at the HP 48 skin's top). */
  margin-inline-start: auto;
  margin-block-start: calc(var(--hp-top) + 2.3rem);
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--code-bg);
  font-size: 14px;
}
#tree-panel.hidden {
  display: none;
}
#tree-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  background: var(--code-bg);
}
#tree-panel-header .title {
  font-weight: 700;
  font-size: 15px;
}
#tree-panel-header .hdr-btns {
  display: flex;
  gap: 0.3rem;
}
#tree-root {
  padding: 0.5rem 0.5rem 0.75rem;
}
#tree-empty {
  color: var(--secondary);
  font-size: 13px;
  padding: 0.25rem;
}
#tree-panel-footer {
  padding: 0.5rem 0.75rem 0.75rem;
  border-top: 1px solid var(--border);
}
/* Collapsible tree. */
.tree ul {
  list-style: none;
  margin: 0;
  padding-left: 1.05em;
}
.tree > ul {
  padding-left: 0;
}
.tree li {
  line-height: 1.5;
  white-space: nowrap;
}
.tree .node {
  display: inline-flex;
  gap: 0.3em;
  align-items: baseline;
}
.tree .twist {
  width: 1em;
  display: inline-block;
  text-align: center;
  color: var(--secondary);
  user-select: none;
}
.tree .twist.clickable {
  cursor: pointer;
}
.tree .name {
  font-weight: 600;
}
.tree .folder > .node > .name {
  color: #1a56c4;
}
.tree .meta {
  color: var(--secondary);
  font-size: 12px;
}
/* Per-node download button (binary HPHP48 object export). Hidden until the row
   is hovered to keep the tree uncluttered. */
.tree .dl {
  font: inherit;
  font-size: 12px;
  line-height: 1;
  box-sizing: border-box;
  width: 24px;
  height: 20px;
  padding: 0;
  margin-left: 0.15em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--theme);
  color: var(--primary);
  cursor: pointer;
  visibility: hidden;
}
.tree .node:hover .dl {
  visibility: visible;
}
.tree .dl:hover {
  background: var(--tertiary);
}
/* Delete button (leaves only): a danger tint so it reads apart from download.
   Shares the .dl box (same width/height as ⤓ and T3). */
.tree .dl.del {
  border-color: rgba(196, 26, 26, 0.35);
  color: #c41a1a;
}
.tree .dl.del svg {
  display: block;
}
.tree .dl.del:hover {
  background: rgba(196, 26, 26, 0.12);
  border-color: #c41a1a;
}
/* Drag-and-drop upload: a folder row lights up while a file hovers over it. */
.tree .folder > .node {
  border-radius: var(--radius);
}
.tree .node.drop-target {
  outline: 2px dashed #1a56c4;
  outline-offset: 1px;
  background: rgba(26, 86, 196, 0.09);
}
/* While a file is being dragged over the panel, the whole tree goes grey so the
   one highlighted drop-target folder clearly shows where the file will land. */
.tree.dragging .name,
.tree.dragging .folder > .node > .name,
.tree.dragging .meta,
.tree.dragging .twist {
  color: var(--secondary);
  transition: color 0.1s ease;
}
.tree.dragging .dl {
  opacity: 0.35;
}
/* The active drop target pops back out of the grey: blue name + stronger fill. */
.tree.dragging .node.drop-target {
  background: rgba(26, 86, 196, 0.16);
}
.tree.dragging .node.drop-target > .name,
.tree.dragging .node.drop-target > .twist {
  color: #1a56c4;
}
#dnd-hint {
  color: var(--secondary);
  font-size: 12px;
  margin-bottom: 0.5rem;
}
/* Panel buttons (share the serial-button look). */
.panel-btn {
  font: inherit;
  font-size: 13px;
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--theme);
  color: var(--primary);
  cursor: pointer;
  line-height: 1.2;
}
.panel-btn:hover:not(:disabled) {
  background: var(--tertiary);
}
#clear-btn {
  width: 100%;
  border-color: #e0b4b4;
  color: #a5352f;
}
#clear-btn:hover:not(:disabled) {
  background: #f7e4e4;
}
/* Always-visible burger toggle, pinned to the stage's right in both the open
   and closed layouts, with its top aligned to the top of the HP 48 skin. It is
   taken out of the flex flow (absolute) so it never pushes the centered
   calculator off-centre when the panel is closed; when the panel is open it
   sits directly above the panel (which starts just below it). */
#tree-toggle {
  font: inherit;
  font-size: 20px;
  line-height: 1;
  padding: 0.35rem 0.55rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--code-bg);
  color: var(--primary);
  cursor: pointer;
  position: absolute;
  inset-block-start: var(--hp-top);
  inset-inline-end: 0;
  margin: 0;
}
#tree-toggle:hover {
  background: var(--tertiary);
}
/* SDL renders here. image-rendering:pixelated keeps the LCD crisp when
   the browser scales the canvas.

   CRITICAL — let SDL own the canvas size; do NOT impose a CSS width/height
   (or anything that makes the browser derive one). This build uses the
   Emscripten SDL2 port. On start it creates the window at the skin's logical
   size (326x733) and sets the backing store to size*devicePixelRatio (e.g.
   652x1466 on a 2x/Retina display). The emulator always draws the skin at a
   FIXED 326:733 aspect and pads any leftover window space with solid black.

   Two traps we hit and must avoid:

   1. `width: auto !important` (the SDL3-era hack): on Retina SDL re-probes
      the canvas by shrinking the backing store, and `auto` width then derives
      from the inline height against a momentarily square intrinsic ratio, so
      the probe reports a SQUARE box. SDL believes external CSS owns the size
      and rebuilds a square 1466x1466 backing store — the skin renders in a
      tall centre strip with wide black bars left and right. Removing the
      override lets SDL's correct 652x1466 (2x) / 326x733 (1x) stand.

   2. `max-height` (capping one axis): it shrinks the height while the width
      stays 326, so SDL rebuilds a too-wide window and the emulator pads it
      with black bars again — the same symptom on short viewports. We cap only
      max-width (protects viewports narrower than the skin); on short screens
      the tall calculator simply scrolls, which never distorts or letterboxes. */
canvas.emscripten {
  border-radius: var(--radius);
  background: #000;
  image-rendering: pixelated;
  outline: none;
  display: block;
  max-width: 100%;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
}
#status {
  min-height: 1.2em;
  font-size: 0.85rem;
  color: var(--secondary);
}
#status.error {
  color: #c0392b;
}
progress {
  width: 320px;
  max-width: 90vw;
}
#controls {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.8rem;
  flex-wrap: wrap;
  justify-content: center;
}
#serial-btn {
  font: inherit;
  font-size: 14px;
  padding: 0.4rem 1rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--code-bg);
  color: var(--primary);
  cursor: pointer;
}
#serial-btn:hover:not(:disabled) {
  background: var(--tertiary);
}
#serial-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
#serial-status {
  color: var(--secondary);
}
#serial-status.on {
  color: #2f855a;
}
#serial-status.err {
  color: #c0392b;
}
