/* ════════════════════════════════════════════════════════════════════
   Canvas tabs — v2.7.03 (browser-style multi-canvas strip)
   ────────────────────────────────────────────────────────────────────
   A strip of tabs hanging from the underside of the topbar. Each tab is an
   independent canvas document; only the active one is live in the single
   Three.js renderer (canvas-tabs.js swaps state snapshots) — inactive tabs
   cost nothing to render. Monochrome, hairline, glass per DESIGN.md
   §2/§3/§6.4; z-index from the §8.4.A table (1390 — resident, fused under
   the topbar at 1400, above floating panels).

   The "hanging tongue" look: tabs have a flat top (fused into the bar) and
   rounded BOTTOM corners (the inverse of normal browser tabs). The active
   tab pulls up 1px to erase the bar's hairline at its width → it reads as
   sucked seamlessly onto the underside of the bar. Inactive tabs sit just
   below that hairline → clearly detached. The full-bleed canvas shows in the
   gaps between tabs, reinforcing the dangling-tongue effect.

   Perf: only the ACTIVE tab carries a backdrop-filter (one extra glass layer,
   to match the topbar seamlessly); inactive tabs use a flat translucent fill
   (no per-tab blur) so N tabs ≠ N compositing layers (DESIGN.md §6.4 guard).
   ════════════════════════════════════════════════════════════════════ */

.canvas-tabs {
  position: fixed;
  top: var(--topbar-h);
  /* v2.7.04: start to the RIGHT of the library dock (+ its resizer) — never
     over the component library; tracks --left-w on collapse/resize (user req). */
  left: calc(var(--left-w) + var(--resizer-w));
  right: 0;
  height: var(--tabstrip-h);
  z-index: 1390;
  display: flex;
  align-items: stretch;
  gap: 1px;                      /* tight — tabs sit almost flush (user req) */
  padding: 0 5px;
  background: transparent;       /* canvas shows in the gaps (glass language) */
  pointer-events: none;          /* only the tabs themselves are interactive */
  font-family: var(--font-ui);
  overflow: hidden;
}
.canvas-tabs > * { pointer-events: auto; }

/* ── Tab (hanging tongue) ─────────────────────────────────────────────── */

.canvas-tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: var(--tabstrip-h);     /* fills the strip; top edge meets the bar */
  flex: 0 1 auto;
  min-width: 60px;
  max-width: 150px;
  padding: 0 3px 0 8px;
  border: 1px solid transparent;
  border-top: none;              /* top fuses into the bar — no top edge */
  border-radius: 0 0 7px 7px;    /* flat top, rounded bottom = "hanging" */
  background: var(--glass-transient);   /* flat translucent (no blur) — cheap */
  color: var(--ink-3);
  font-size: 11px;
  font-weight: 500;
  cursor: pointer;
  user-select: none;
  transition:
    background-color 120ms ease,
    color 120ms ease,
    box-shadow 120ms ease;
}

/* Inactive-tab hover — match the unified hover system (border + bg). The
   active tab still uses the glass/--glass-border treatment above (it's a
   stronger affordance than hover; intentional). */
.canvas-tab:not(.is-active):hover {
  background: var(--hover-bg);
  border-color: var(--hover-border);
  color: var(--ink-1);
}

/* Active tab — sucked onto the underside of the bar. Same glass as the topbar
   (incl. backdrop-filter) + margin-top:-1px to overlap the bar's hairline so
   the join is seamless; a soft downward shadow lifts it over the canvas. */
.canvas-tab.is-active {
  margin-top: -1px;
  background: var(--float-bg);
  -webkit-backdrop-filter: blur(var(--float-blur)) saturate(var(--float-sat));
  backdrop-filter: blur(var(--float-blur)) saturate(var(--float-sat));
  border-color: var(--ctl-line);   /* v2 affordance：active tab 边界达标可辨（U11）*/
  border-top: none;
  color: var(--ink-1);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06), var(--float-edge);
}

.canvas-tab:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--overlay-2);
}

/* ── Drag-to-reorder (v2.7.05) ─────────────────────────────────────────────
   Siblings glide to open the gap; the grabbed tab follows the pointer 1:1 and
   lifts. overflow:visible during a reorder lets the lift shadow show (the strip
   sits below the topbar row, so a tab can't spill onto the bar controls). */
.canvas-tabs.is-reordering { overflow: visible; }
.canvas-tabs.is-reordering .canvas-tab {
  transition: transform 200ms cubic-bezier(0.2, 0, 0, 1);
}
.canvas-tab.is-grabbing {
  transition: none !important;          /* track the pointer with no lag */
  z-index: 6;
  cursor: grabbing;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.16), var(--float-edge);
  filter: brightness(1.02);
}
.canvas-tab.is-settling {
  transition: transform 200ms cubic-bezier(0.2, 0, 0, 1);
  z-index: 6;
}

/* Entrance for a freshly-opened tab (subtle drop + fade; never animate blur). */
.canvas-tab.is-entering {
  animation: canvas-tab-pop var(--dur-enter) var(--ease-out);
}
@keyframes canvas-tab-pop {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* ── Tab inner bits ───────────────────────────────────────────────────── */

.canvas-tab-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Inline rename (dblclick) — keep the text crisp, suppress the native outline. */
.canvas-tab-label[contenteditable="true"] {
  outline: none;
  cursor: text;
  text-overflow: clip;
  color: var(--ink-1);
}

.canvas-tab-close {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  opacity: 0.45;                 /* v2 affordance (U10)：常显淡态，不 hover 也知可关；hover/active → 1 */
  transition: background-color 100ms ease, color 100ms ease, opacity 100ms ease;
}
.canvas-tab:hover .canvas-tab-close,
.canvas-tab.is-active .canvas-tab-close { opacity: 1; }
.canvas-tab-close { border: 1px solid transparent; transition: background-color 100ms ease, color 100ms ease, opacity 100ms ease, border-color 100ms ease; }
.canvas-tab-close:hover  { background: var(--hover-bg); color: var(--ink-1); border-color: var(--hover-border); }
.canvas-tab-close:active { background: var(--active-bg); border-color: var(--active-border); }
.canvas-tab-close svg { display: block; }

/* Single tab → hide its close affordance (can't close the last canvas). */
.canvas-tabs[data-count="1"] .canvas-tab-close { display: none; }

/* ── New-tab "+" at the end of the strip (browser convention) ─────────── */

.canvas-tab-new {
  flex: 0 0 auto;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-left: 1px;
  border: none;
  border-radius: 5px;
  background: var(--ctl-rest);   /* v2 affordance：新建画布钮静止即有座（U10）*/
  color: var(--ink-3);
  cursor: pointer;
  transition: background-color 100ms ease, color 100ms ease;
}
.canvas-tab-new { border: 1px solid transparent; transition: background-color 100ms ease, color 100ms ease, border-color 100ms ease; }
.canvas-tab-new:hover  { background: var(--hover-bg); color: var(--ink-1); border-color: var(--hover-border); }
.canvas-tab-new:active { background: var(--active-bg); border-color: var(--active-border); }
.canvas-tab-new:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--overlay-2); }
.canvas-tab-new svg { display: block; }
