/* ─────────────────────────────
   PROJECT STYLES — Folder Structure
   ─────────────────────────────

   Project-specific styles for the full-screen diagram tool. The
   design system has no app-shell/canvas primitives, so the shell,
   canvas layers, and tree component live here. Everything uses
   semantic tokens; the only pixel values are the diagram's geometry
   contract with assets/js/tree-layout.js (rows 40px, connector
   cells 30x40, icons 24px, gaps 5px — from the Figma spec).
   ───────────────────────────── */


/* -- App shell -- */

body.is-app {
  overflow: hidden;
}

.app {
  position: fixed;
  inset: 0;
  height: 100dvh;
  background-color: var(--background-primary);
}


/* -- Canvas -- */

.canvas-viewport {
  position: absolute;
  inset: 0;
  overflow: hidden;
  touch-action: none;
  cursor: grab;
}

.canvas-viewport.is-panning {
  cursor: grabbing;
}

.canvas-surface {
  position: absolute;
  top: 0;
  left: 0;
  transform-origin: 0 0;
}

.canvas-surface.is-animating {
  transition: transform var(--duration-m) var(--ease-out);
}


/* -- Tree rows -- */
/* Geometry contract with tree-layout.js: do not restyle sizes. */

.tree-item {
  position: absolute;
  top: 0;
  left: 0;
  height: 40px;
  display: flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
  color: var(--text-primary);
  cursor: pointer;
  transition:
    transform var(--duration-m) var(--ease-out),
    color var(--duration-s) var(--ease-out),
    opacity var(--duration-s) var(--ease-out);
}

.tree-item.is-entering {
  opacity: 0;
}

/* Selected row (the focused node) — a subtle pill behind icon + label.
   Painted on a pseudo so row geometry stays untouched; the row's inline
   transform makes it a stacking context, so z-index -1 keeps it under
   the icon and label but above the connector layer. */
.tree-item::before {
  content: "";
  position: absolute;
  inset: 4px -6px;
  z-index: -1;
  border-radius: var(--radius-xs);
  background-color: transparent;
  transition: background-color var(--duration-s) var(--ease-out);
}

.tree-item.is-selected::before {
  background-color: var(--background-faded);
}

/* Rows fade only when a sibling folder is open (set by tree-layout);
   hovering a faded row brings it back to full strength. */
.tree-item.is-faded {
  color: var(--text-faded);
}

.tree-item.is-faded:hover,
.tree-item.is-faded:focus-visible {
  color: var(--text-primary);
}

.tree-item:focus-visible {
  outline: none;
}

.tree-item:focus-visible .tree-label {
  outline: 2px solid var(--input-focus);
  outline-offset: 2px;
  border-radius: var(--radius-2xs);
}

.tree-icon {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}

.tree-label {
  font-family: var(--font-primary);
  font-size: var(--font-l);
  line-height: 1.3;
  letter-spacing: -0.01em;
}

.tree-measure-probe {
  position: absolute;
  visibility: hidden;
  pointer-events: none;
}

.tree-rename-input {
  font: inherit;
  letter-spacing: inherit;
  color: var(--text-primary);
  background-color: var(--input-background);
  border: var(--border-s) solid var(--input-focus);
  border-radius: var(--radius-2xs);
  padding: 0 var(--space-2xs);
  min-height: 0;
  height: 32px;
  /* The engine's width:100% collapses inside the shrink-wrapped label;
     tree-edit.js sets an explicit ch width and grows it while typing. */
  width: auto;
}


/* -- Connectors -- */
/* Figma shows connector strokes at full strength on every branch. */

.tree-connectors {
  color: var(--text-primary);
}

.tree-connector {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 30px;
  height: 40px;
  transition: transform var(--duration-m) var(--ease-out);
}


/* -- Row actions (edit mode, shown on the selected row) -- */
/* A solid chip floated past the label so it doesn't stretch the row;
   its opaque background covers the connector arm cleanly. Revealed by
   clicking a row (selection), not hover, so it never fights the
   add-pills between rows. */

.tree-item-actions {
  display: none;
  position: absolute;
  left: 100%;
  top: 50%;
  transform: translateY(-50%);
  margin-left: 5px;
  align-items: center;
  gap: var(--space-2xs);
  background-color: var(--background-primary);
  border: var(--border-s) solid var(--border-faded);
  border-radius: var(--radius-s);
  padding: var(--space-2xs);
  box-shadow: 0 2px 8px var(--black-alpha-10);
}

.is-edit-mode .tree-item.is-selected .tree-item-actions {
  display: flex;
}

/* Separates the organising buttons (add, move, indent) from
   rename/delete; the chip's gap provides the spacing. */
.tree-item-actions .divider--vertical {
  margin: 0;
}


/* -- Add pills (edit mode) -- */
/* Pills sit on the boundary line between rows; the dashed rules are
   the always-on "this is editable" signal, the button fades in on
   hover/focus of the pill area. */

.tree-gaps {
  display: none;
}

.is-edit-mode .tree-gaps {
  display: block;
}

.add-pill {
  position: absolute;
  top: 0;
  left: 0;
  height: 24px;
  margin-top: -12px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
}

.add-pill::before,
.add-pill::after {
  content: "";
  flex: 1;
  border-top: var(--border-s) dashed var(--border-faded);
}

.add-pill-btn,
.add-pill-type {
  display: none;
  align-items: center;
  gap: var(--space-2xs);
  border: none;
  background-color: var(--background-faded);
  color: var(--text-faded);
  font-family: var(--font-primary);
  font-size: var(--font-2xs);
  letter-spacing: -0.01em;
  border-radius: var(--radius-xs);
  padding: var(--space-2xs) var(--space-s);
  cursor: pointer;
  transition: color var(--duration-s) var(--ease-out);
}

.add-pill-type {
  padding: var(--space-2xs);
}

.add-pill:hover .add-pill-btn,
.add-pill:hover .add-pill-type {
  display: flex;
}

.add-pill-btn:hover,
.add-pill-type:hover {
  color: var(--text-primary);
}

.add-pill-icon,
.add-pill-type-icon {
  width: 14px;
  height: 14px;
}


/* -- Floating chrome -- */
/* Card-like surfaces; z-index below the design system's tooltip (800),
   toast (900), and the native dialog top layer. */

.app-toolbar,
.zoom-controls,
.edit-bar {
  position: fixed;
  z-index: 700;
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  background-color: var(--background-primary);
  border: var(--border-s) solid var(--border-faded);
  border-radius: var(--radius-l);
  padding: var(--space-2xs);
  box-shadow: 0 4px 16px var(--black-alpha-10);
}

.app-toolbar {
  top: var(--space-l);
  right: var(--space-l);
}

/* Logo — fixed top left; inline SVG wordmark on currentColor so it
   follows the theme. 246/25 is the artwork's natural geometry.
   The whole logo is a transparent button that opens the About modal;
   hovering it gets the button's subtle background and reveals the
   info icon to the wordmark's right. */
.app-logo {
  position: fixed;
  top: var(--space-l);
  left: var(--space-l);
  z-index: 700;
}

.app-logo-button {
  color: var(--text-primary);
  gap: var(--space-s);
}

.app-logo-info {
  width: 24px;
  height: 24px;
  opacity: 0;
  transition: opacity var(--duration-s) var(--ease-out);
}

.app-logo-button:hover .app-logo-info,
.app-logo-button:focus-visible .app-logo-info {
  opacity: 1;
}

.app-logo .svg-logo {
  display: block;
  width: 246px;
  aspect-ratio: 246 / 25;
}

@media (max-width: 720px) {
  .app-logo .svg-logo {
    width: 164px;
  }
}

.zoom-controls {
  bottom: var(--space-l);
  right: var(--space-l);
}

.edit-bar {
  bottom: var(--space-l);
  left: var(--space-l);
}

.edit-bar .form-toggle {
  padding: 0 var(--space-s);
  gap: var(--space-xs);
}

.icon-flip-x {
  transform: scaleX(-1);
}

.toolbar-divider {
  width: var(--border-s);
  align-self: stretch;
  background-color: var(--border-faded);
}


/* -- Dialogs -- */

/* About dialog: wordmark centred above the description; the visually
   hidden title means the close button needs pushing to the right. */
[data-dialog="about"] .dialog-close {
  margin-left: auto;
}

.about-logo {
  display: flex;
  justify-content: center;
  color: var(--text-primary);
}

.about-logo .svg-logo {
  width: 246px;
  max-width: 100%;
  aspect-ratio: 246 / 25;
}

/* No backdrop blur — keep the diagram readable behind the modal. */
.dialog::backdrop {
  backdrop-filter: none;
}

/* Toasts above everything, including chrome and tooltips. */
.toast-container {
  z-index: 9999;
}

.import-textarea,
.export-output {
  width: 100%;
  font-family: var(--font-code);
  font-size: var(--font-s);
  white-space: pre;
  overflow-x: auto;
}

.export-output {
  min-height: 16rem;
}


/* -- Small screens: icon-only toolbar -- */

@media (max-width: 720px) {
  .app-toolbar .button-text {
    display: none;
  }

  .app-toolbar {
    max-width: calc(100vw - var(--space-l) * 2);
  }
}


/* -- Reduced motion -- */

@media (prefers-reduced-motion: reduce) {
  .canvas-surface.is-animating,
  .tree-item,
  .tree-connector {
    transition: none;
  }
}


/* -- Print: the diagram only -- */

@media print {
  .app-toolbar,
  .zoom-controls,
  .tree-gaps,
  .tree-item-actions {
    display: none;
  }

  /* Selection is a screen affordance — keep it off the page. */
  .tree-item.is-selected::before {
    background-color: transparent;
  }
}


/* -- Dark mode toggle (icon swap) -- */
/* Icons injected by assets/js/theme-toggle.js; the framework no
   longer ships these rules, so they live here alongside the script. */
.dark-mode-toggle .dark-mode-icon-dark {
  display: none;
}

[data-theme="dark"] .dark-mode-toggle .dark-mode-icon-light {
  display: none;
}

[data-theme="dark"] .dark-mode-toggle .dark-mode-icon-dark {
  display: flex;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .dark-mode-toggle .dark-mode-icon-light {
    display: none;
  }

  :root:not([data-theme]) .dark-mode-toggle .dark-mode-icon-dark {
    display: flex;
  }
}
