/* pane.css — the single pane. (Alfred, 2026-08-21: "get rid of the bottom
 * nav, innovate with the graph… the graph is the face.")
 *
 * One surface. At rest the graph fills it. Select a node and the SAME
 * element shrinks into a circular porthole top-right — the slate, ported
 * from the original Foodie's #vvSlate — while chips take the pane. The
 * chips are the nav; there is no bar.
 *
 * The graph never moves in the DOM. #pane-graph is position:fixed and
 * flips between two geometries with one class, so d3's simulation, the
 * viewBox and every listener survive the transition. Two elements would
 * mean two graphs, and the second one would drift.
 *
 * Colours are palette tokens only (--pg-*, --surface-paper, --ink, --forest,
 * --rule). No raw hex outside the shadows. Two traps: paper is
 * --surface-paper, not --paper (--paper is undefined, so it silently falls
 * back to a light hex and whites out the pane in night), and text is --ink,
 * never --bark or --gold — both are decorative accents that resolve to gold
 * or brown in some palettes.
 */

:root {
  --pane-slate: 320px;
  --pane-ease: cubic-bezier(.2, .8, .2, 1);
  --pane-mo-1: 60ms;
  --pane-mo-2: 90ms;
  --pane-mo-3: 150ms;
}
@media (max-width: 760px) {
  :root { --pane-slate: 220px; }
}

/* ============================================================
   THE PANE
   Fixed, full-bleed, under the ticker. It is the app's rest
   state: hidden the moment a destination opens, back on ← Back.
   ============================================================ */
.pane {
  position: fixed;
  left: 0; right: 0;
  top: var(--pane-top, 0px);
  bottom: 0;
  z-index: 9400;
  display: flex;
  flex-direction: column;
  background: var(--surface-paper, #FDFCF7);
  padding: 0 max(14px, env(safe-area-inset-left)) max(14px, env(safe-area-inset-bottom)) max(14px, env(safe-area-inset-right));
  overflow: hidden;
  opacity: 1;
  transition: opacity var(--pane-mo-2) var(--pane-ease);
}
.pane[hidden] { display: none; }
.pane.is-leaving { opacity: 0; pointer-events: none; }

/* The rolodex is a panel's own sub-nav, fixed to the bottom edge at z-index 9610
   — above the pane's 9400. While the pane is up it belongs to a page nobody is
   looking at, and it was painted over the last two chips in the drawer. */
body.pane-open .rolodex-bar { display: none; }
/* The glass sub-nav pull is NOT the same story: it is the app's own sub-nav,
   and on the app the pane is the rest state, so hiding it while the pane is up
   removes the sub-nav entirely. It floats at z-index 99986 on the bottom edge,
   44px tall, 12px up — and it covered the centre of the last chip in the
   drawer. So the pane ends above its footprint instead. */
body:has(.subnav-pull) .pane {
  padding-bottom: calc(max(14px, env(safe-area-inset-bottom)) + 56px);
}

/* ---- the section strip: news · media · network · notes · money ---- */
.pane-modes {
  display: flex; gap: 6px;
  padding: 10px 0 8px;
  flex: 0 0 auto;
}
.pane-mode {
  flex: 1 1 0; min-height: 44px;
  border: 1px solid var(--rule, #E5DFD2);
  border-radius: 999px;
  background: transparent;
  color: var(--ink-mute, #6E6A60);
  font: 700 11.5px/1 var(--font-mono, monospace);
  letter-spacing: .08em; text-transform: uppercase;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  transition: background var(--pane-mo-1) var(--pane-ease),
              color var(--pane-mo-1) var(--pane-ease),
              border-color var(--pane-mo-1) var(--pane-ease);
}
/* --on-primary, never --gold: --gold aliases to --accent-bark (brown) in every
   light palette, which put a brown label on a dark-green fill at 1.09:1.
   scratch/contrast-check.mjs measures the rendered pixels in all six palettes. */
.pane-mode[aria-selected="true"] {
  background: var(--forest, #2D5016);
  border-color: var(--forest, #2D5016);
  color: var(--on-primary, var(--pg-on-primary, #F4ECD8));
  font-size: 12.5px;
}
.pane-mode:active { transform: scale(.94); background: var(--forest, #2D5016); color: var(--on-primary, #F4ECD8); }

/* ---- a press must LOOK like a press (Alfred, 2026-08-21) ----
   The dot swells under the finger, and the chosen country keeps a ring. */
.pane-node circle {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 120ms var(--pane-ease, ease), stroke-width 120ms var(--pane-ease, ease);
}
.pane-node.is-pressed circle:nth-of-type(2) { transform: scale(1.45); }
.pane-node.is-selected circle:nth-of-type(2) {
  stroke: var(--forest, #2D5016);
  stroke-width: 3.5;
  transform: scale(1.2);
}

/* ---- the stage the graph sits over at rest ----
   The floor matters: with `min-height: 0` the drawer's seventeen chips won the
   flex fight and squeezed the graph to a 90px thumbnail — legible labels on an
   illegible map. The drawer scrolls (it already has overflow-y:auto), so it is
   the one that should give. "The graph is the face." */
.pane-stage { position: relative; flex: 1 1 auto; min-height: 240px; }
@media (min-width: 761px) { .pane-stage { min-height: 320px; } }

/* The heat scale means nothing unless it is written down somewhere. Colours are
   the swatches' own — they are data, set inline from pane.js's HEAT — but the
   words beside them are --ink like every other label in here. */
.pane-legend {
  flex: 0 0 auto;
  display: flex; flex-wrap: wrap; gap: 4px 12px;
  padding: 6px 2px 0;
}
.pane-legend:empty { display: none; }
.pane-heat { display: inline-flex; align-items: center; gap: 5px; }
.pane-heat-dot {
  width: 9px; height: 9px; border-radius: 50%;
  border: 1px solid var(--surface-paper, #FDFCF7);
  flex: 0 0 auto;
}
.pane-heat-lab {
  font: 700 10px/1 var(--font-mono, monospace);
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink, #1A1A1A);
}

.pane-meta {
  flex: 0 0 auto;
  padding: 6px 2px 8px;
  font: 600 12px/1.35 var(--font-mono, monospace);
  color: var(--ink, #1A1A1A);
  letter-spacing: .01em;
}

/* ---- chips: the nav ----
   Text here is --ink, never --bark: --bark is a decorative accent that resolves
   to gold #C9A24F in night and river, which reads 2.4:1 on white card paper. */
.pane-chips {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-wrap: wrap; align-content: flex-start;
  gap: 8px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 8px;
}
.pane-chips[hidden] { display: none; }
.pane-chip {
  flex: 1 1 240px; min-width: 0; min-height: 56px;
  display: flex; align-items: center; gap: 10px;
  text-align: left;
  padding: 10px 13px;
  border: 1px solid var(--rule, #E5DFD2);
  border-radius: 14px;
  background: var(--pg-card, rgba(255,255,255,.6));
  color: var(--ink, #1A1A1A);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  transition: transform var(--pane-mo-1) var(--pane-ease),
              border-color var(--pane-mo-1) var(--pane-ease);
}
.pane-chip:active { transform: scale(.95); filter: brightness(.92); }
.pane-chip .glyph {
  flex: 0 0 auto; width: 22px; height: 22px;
  color: var(--forest, #2D5016);
}
.pane-chip .body { min-width: 0; flex: 1 1 auto; }
.pane-chip .lab {
  display: block; font: 600 13.5px/1.3 var(--font-serif, Georgia, serif);
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.pane-chip .sub {
  display: block; margin-top: 3px;
  font: 600 10.5px/1 var(--font-mono, monospace);
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-mute, #6E6A60);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* A chip that leads somewhere permanent (a door) reads heavier than one
   that leads to a single story. */
.pane-chip.door { flex: 1 1 130px; border-color: var(--forest, #2D5016); }
.pane-chip.door .lab { font-family: var(--font-mono, monospace); font-weight: 700; letter-spacing: .04em; }

/* ---- the doors row at rest ---- */
.pane-doors { flex: 0 0 auto; display: flex; flex-wrap: wrap; gap: 8px; padding-top: 4px; align-items: stretch; }
.pane-doors[hidden] { display: none; }

/* Three doors and the drawer toggle shared one 390px row, which crushed the
   labels to "G." and "W." — a door that no longer names where it goes. The
   toggle takes its own row and the door internals tighten so GAZETTE /
   MARKETS / WALLET fit whole. pane-check.mjs asserts they are not truncated. */
.pane-doors .pane-more { flex: 1 0 100%; order: 2; }
.pane-doors .pane-chip.door { order: 1; padding: 10px 9px; gap: 8px; }
.pane-doors .pane-chip.door .glyph { width: 18px; height: 18px; }

/* The "everything" drawer. The bar reached four destinations; the app has
   twenty. A drawer scrolls, a bar does not, so this is the surface that can
   still hold the app after the next five things get built. */
.pane-more {
  flex: 0 0 auto; min-height: 44px; padding: 0 14px;
  border: 1px solid var(--rule, #E5DFD2); border-radius: 12px;
  background: transparent; color: var(--ink, #241E14);
  font: 700 11.5px/1 var(--font-mono, monospace); letter-spacing: .06em;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.pane-more[aria-expanded="true"] {
  background: var(--forest, #2D5016);
  border-color: var(--forest, #2D5016);
  color: var(--on-primary, var(--pg-on-primary, #F4ECD8));
}
.pane-drawer {
  flex: 0 1 auto; min-height: 0; overflow-y: auto;
  display: flex; flex-wrap: wrap; gap: 8px; padding-top: 8px;
  -webkit-overflow-scrolling: touch;
}
.pane-drawer[hidden] { display: none; }

/* ---- the clear-selection pill ---- */
.pane-clear {
  flex: 0 0 auto; align-self: flex-start;
  min-height: 44px; padding: 0 16px; margin-top: 2px;
  border: 1px solid var(--rule, #E5DFD2); border-radius: 999px;
  background: transparent; color: var(--ink-mute, #6E6A60);
  font: 700 11.5px/1 var(--font-mono, monospace); letter-spacing: .06em;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.pane-clear[hidden] { display: none; }

/* ============================================================
   THE GRAPH / THE SLATE — one element, two geometries.
   At rest it is pinned over .pane-stage. Selected, it collapses
   into the porthole: circular, radial-masked so it fades into
   the paper instead of sitting in a box, and draggable.
   ============================================================ */
/* pointer-events:none, not auto. This host is a 362x546 fixed sheet at z-index
   9450 pinned over the stage, and where it paints nothing it is still a hit
   surface — it sat invisibly on top of the Gazette's country graph and ate
   every tap on it. An SVG root hit-tests over its whole box no matter what is
   drawn inside, so transparency is not the same as being out of the way.
   The parts that are actually there take their taps back below. */
#pane-graph {
  position: fixed;
  z-index: 9450;
  border-radius: 0;
  overflow: hidden;
  pointer-events: none;
  transition: top var(--pane-mo-3) var(--pane-ease),
              left var(--pane-mo-3) var(--pane-ease),
              width var(--pane-mo-3) var(--pane-ease),
              height var(--pane-mo-3) var(--pane-ease),
              border-radius var(--pane-mo-3) var(--pane-ease),
              opacity var(--pane-mo-2) var(--pane-ease);
}
#pane-graph[hidden] { display: none; }
#pane-graph svg { width: 100%; height: 100%; display: block; }

/* The svg takes its taps back: the host stays pointer-events:none so its box
   never eats taps while hidden or mid-transition, but the drawing itself must
   hear every finger — nodes for taps, paper for pinch/wheel zoom (d3.zoom).
   The old .gnode/.glinks/.glabels list named the previous renderer's classes;
   pane.js paints .pane-node, so every node was pointer-DEAD and taps fell
   through to the stage. Alfred, 2026-08-21: "I press it, I get no indication
   I pressed anything." */
#pane-graph svg { pointer-events: auto; }

/* ---- the WebGL renderer's overlay (graph-gl.js) ----
   The engine paints its balls on a canvas and its names in the DOM above it.
   The names land on top of other countries' balls, so each one gets the same
   frosted plate the SVG path cut behind its <text> — Alfred, 2026-08-21: "the
   graph over the face of the object is unreadable… put it over a frosted
   area." The count rides inside the ball, where the fill is already dark. */
#pane-graph .gg-node { pointer-events: auto; }
#pane-graph .gg-count {
  font: 700 12px/1 var(--font-mono, ui-monospace, Menlo, monospace);
  color: var(--on-primary, #F4ECD8);
  pointer-events: none;
}
/* Hung below the ball, not laid inside the button's flex flow — an opaque
   plate sitting on the sphere cut every one of them into a half-dome. */
#pane-graph .gg-label {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: 2px;
  padding: 1px 4px;
  border-radius: 4px;
  background: var(--surface-paper, #FDFCF7);
  color: var(--ink, #1A1A1A);
  font: 700 11px/1.2 system-ui, -apple-system, sans-serif;
  white-space: nowrap;
  pointer-events: none;
}

/* Slated, the porthole itself is the drag grip, so the host takes taps again —
   but clipped to the circle it actually draws. clip-path clips hit-testing as
   well as paint, which is what keeps the four corners of this box from
   stealing taps from whatever is underneath. */
#pane-graph.is-slate {
  width: var(--pane-slate); height: var(--pane-slate);
  border-radius: 50%;
  pointer-events: auto;
  clip-path: circle(50% at 50% 50%);
  cursor: grab;
  background: radial-gradient(circle at 50% 50%,
    var(--forest-tint, #E4EBD8) 0%, var(--surface-paper, #FDFCF7) 56%, transparent 100%);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 56%, transparent 100%);
          mask-image: radial-gradient(circle at 50% 50%, #000 56%, transparent 100%);
}
#pane-graph.is-slate.is-dragging { cursor: grabbing; transition: none; }

/* The outer ring is the drag grip; the middle stays tappable so nodes can
   still be picked inside the porthole. Purely a hit surface — invisible. */
#pane-slate-grip { position: absolute; inset: 0; border-radius: 50%; pointer-events: none; }

/* ============================================================
   ← BACK — the same pill on every destination. Top-left, above
   the fold, 44px, never scrolled to. This is the answer to
   "how do I get out of chess" (bug df874c38).
   ============================================================ */
.pane-back {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  left: max(12px, env(safe-area-inset-left));
  z-index: 9700;
  min-height: 44px; padding: 0 18px 0 14px;
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--rule, #E5DFD2); border-radius: 999px;
  background: var(--pg-bar-strong, rgba(253,252,247,.92));
  -webkit-backdrop-filter: blur(18px) saturate(170%);
          backdrop-filter: blur(18px) saturate(170%);
  color: var(--ink, #1A1A1A);
  font: 700 12.5px/1 var(--font-mono, monospace); letter-spacing: .04em;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(74, 46, 22, .12);
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.pane-back[hidden] { display: none; }
.pane-back:active { transform: scale(.96); }

/* ============================================================
   DESKTOP — the pane is a column, not a full bleed. The slate
   goes bigger and the chips run two-up.
   ============================================================ */
@media (min-width: 761px) {
  .pane { padding-left: max(28px, env(safe-area-inset-left)); padding-right: max(28px, env(safe-area-inset-right)); }
  .pane-modes { max-width: 420px; }
}

@media (prefers-reduced-motion: reduce) {
  #pane-graph, .pane, .pane-chip, .pane-mode { transition-duration: 1ms !important; }
}
