/* Local Pashto font — Arabic-script glyphs only (unicode-range), so Latin
   text falls through to the system stack. NO external font requests. */
@font-face {
  font-family: 'Noto Naskh Arabic';
  src: url('vendor/fonts/noto-naskh-arabic.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;
}

/* Reset & Variables */
:root {
  /* ======================= Design tokens (light) =======================
     The light "Classic" default. Old var names below are MAPPED onto these
     tokens so every existing consumer (JS add-ons, themes.js) stays wired. */

  /* Brand */
  --primary: #0f766e;          /* deep teal — trustworthy, heritage feel */
  --primary-hover: #115e59;
  --primary-soft: #ccfbf1;     /* tinted backgrounds, selected states */

  /* Surfaces */
  --canvas-bg: #eef2f6; /* deeper soft grey-blue so white cards + chrome pop */
  --surface: #ffffff;
  --border: #e2e8f0;

  /* Text */
  --text: #0f172a;

  /* Gender accents (card indicator only, not text) */
  --male: #3b82f6;
  --female: #ec4899;
  --other: #a855f7;
  --unknown: #94a3b8;

  /* Geometry */
  --radius-card: 12px;
  --radius-control: 8px;
  --shadow-card: 0 6px 10px -2px rgb(0 0 0 / 0.12), 0 3px 5px -3px rgb(0 0 0 / 0.1); /* one notch up from shadow-md: cards must read on the deeper canvas */
  --shadow-card-hover: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --focus-ring: 0 0 0 2px var(--surface), 0 0 0 4px var(--primary);

  /* Motion */
  --transition: 150ms ease;

  /* ============== Legacy vars → tokens (do not rename) ============== */
  --bg-primary: var(--canvas-bg);
  --bg-secondary: var(--surface);
  --bg-tertiary: #e2e8f0;
  --text-primary: var(--text);
  --text-secondary: #64748b;   /* Slate 500 — labels/captions on white */
  --text-muted: #94a3b8;       /* Slate 400 — placeholders/icons */

  --accent-blue: var(--male);
  --accent-pink: var(--female);
  --accent-purple: var(--other);
  --accent-gray: var(--unknown);
  --accent-teal: var(--primary); /* Selected / Highlight */
  --accent-rgb: 15, 118, 110;    /* rgb triple of --primary — MUST be retuned together with --primary (rgba() can't take a hex token) */

  --border-color: var(--border);
  --glass-bg: rgba(255, 255, 255, 0.97); /* toolbar + theme popover chrome */
  --glass-border: rgba(15, 23, 42, 0.08);

  --font-family: 'Noto Naskh Arabic', 'Segoe UI Variable Display', 'Segoe UI', Tahoma, system-ui, -apple-system, sans-serif; /* Noto only claims Arabic-script codepoints */
  --transition-speed: 0.15s;

  --panel-solid: rgba(255, 255, 255, 0.96);
  --shadow-pop: 0 14px 34px rgba(15, 23, 42, 0.16), 0 2px 8px rgba(15, 23, 42, 0.08);

  /* Chrome recipes (light values; the static dark-theme block re-points
     every one of these for Ocean/Forest/Royal/Crimson) */
  --head-tint: rgba(15, 23, 42, 0.03);   /* header/tab/modal-cap strips */
  --hover-tint: rgba(15, 23, 42, 0.05);  /* ghost-button & row hovers */
  --chip-bg: rgba(15, 23, 42, 0.03);     /* task rows, chips, tiles */
  --panel-tint: rgba(15, 23, 42, 0.03);  /* inset panels */
  --pill-bg: rgba(15, 23, 42, 0.04);     /* toolbar pills (search/zoom/lang) */
  --row-line: rgba(15, 23, 42, 0.07);    /* hairline row separators */
  --track-tint: rgba(15, 23, 42, 0.08);  /* progress-bar tracks */
  --divider: rgba(15, 23, 42, 0.14);     /* toolbar dividers */
  --scroll-thumb: #cbd5e1;
  --btn-bg: var(--surface);
  --btn-border: #cbd5e1;
  --btn-hover-bg: #f1f5f9;
  --btn-hover-border: #94a3b8;
  --input-bg: var(--surface);
  --input-border: #cbd5e1;
  --input-focus-bg: var(--surface);
  --input-focus-shadow: 0 0 0 2px var(--primary-soft);
  --card-border: var(--border);
  --avatar-bg: #e2e8f0;
  --avatar-ink: #475569;
  --toast-bg: rgba(255, 255, 255, 0.98);
  --toast-border: rgba(15, 23, 42, 0.1);
  --ok-ink: #059669;
  --warn-ink: #b45309;
  --danger-ink: #dc2626;
  --danger-bg: #dc2626;
  --danger-fg: #ffffff;
  --danger-border: transparent;
  --danger-hover-bg: #b91c1c;
  --danger-hover-border: transparent;

  /* Workspace (deeper blue-grey canvas gives the white chrome depth; themes override) */
  --viewport-bg: #eef2f6;
  --canvas-dot: #cbd5e1;   /* visible at normal zoom on the deeper canvas */
  --band-tint: rgb(148 163 184 / 0.09); /* generation-labels.js reads this for the alternating bands */
  --gen-label-color: rgba(15, 23, 42, 0.62);
  --spouse-line: #8b95a5;

  /* Radii scale */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;

  /* Ghost cards (dark themes override) */
  --ghost-bg: rgba(255, 255, 255, 0.6);
  --ghost-border: rgba(100, 116, 139, 0.55);
  --ghost-name: #334155;

  /* Stats charts (stats-charts.js reads these per draw) */
  --chart-label: #64748b;
  --chart-count: #0f172a;
  --chart-grid: rgba(15, 23, 42, 0.07);
  --chart-axis: rgba(15, 23, 42, 0.16);
  --chart-accent: var(--primary);

  --card-width: 200px;
  --card-height: 90px;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-family);
  background-color: var(--bg-primary);
  color: var(--text-primary);
  overflow: hidden;
  height: 100vh;
  width: 100vw;
  overscroll-behavior: none; /* no rubber-band bounce on phones */
}

/* App Layout */
#app-container {
  display: flex;
  height: 100vh;
  width: 100vw;
}

/* Sidebar Styling */
#sidebar {
  width: 380px;
  min-width: 380px;
  background-color: var(--bg-secondary);
  border-inline-end: 1px solid var(--border-color);
  display: flex;
  flex-direction: column;
  height: 100%;
  z-index: 10;
  transition: margin-inline-start 0.3s ease;
}

#sidebar.collapsed {
  margin-inline-start: -380px;
}

.sidebar-header {
  padding: 14px 20px;
  border-bottom: 1px solid var(--border-color);
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--head-tint);
}

.logo {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  font-size: 1.1875rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  /* Brand wordmark: sky-blue -> --primary. Retune #0284c7 together with --primary if the brand hue changes. */
  background: linear-gradient(135deg, #0284c7, var(--primary));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.logo i {
  -webkit-text-fill-color: initial;
  background: initial;
  color: var(--accent-teal);
}

/* Brand medallion — same teal-tinted treatment as the empty-state badge */
.logo-mark {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  font-size: 1.0625rem;
  background: rgba(var(--accent-rgb), 0.1);
  border: 1px solid rgba(var(--accent-rgb), 0.25);
  box-shadow: inset 0 0 12px rgba(var(--accent-rgb), 0.08);
}

.logo-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.2;
}

.logo-name {
  white-space: nowrap;
}

/* Pashto subtitle — opts back out of the gradient text fill */
.logo-sub {
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0; /* Arabic script — tracking breaks letter joining */
  text-align: start;
  white-space: nowrap;
  -webkit-text-fill-color: var(--text-secondary);
}

.sidebar-tabs {
  display: flex;
  border-bottom: 1px solid var(--border-color);
  background: var(--head-tint);
}

.tab-btn {
  position: relative;
  flex: 1;
  padding: 12px 4px;
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color var(--transition), background-color var(--transition), border-color var(--transition);
  white-space: nowrap;
}

.tasks-badge {
  display: none; /* JS switches to inline-flex when there are tasks */
  background: #ef4444;
  color: #fff;
  font-size: 0.625rem;
  font-weight: 700;
  border-radius: 999px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  align-items: center;
  justify-content: center;
  margin-inline-start: 2px;
  vertical-align: middle;
}

.tab-btn:hover {
  color: var(--text-primary);
  background: var(--hover-tint);
}

.tab-btn.active {
  color: var(--accent-teal);
  border-bottom-color: var(--accent-teal);
  background: linear-gradient(180deg, rgba(var(--accent-rgb), 0.07), transparent);
}

.sidebar-content {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}

/* Custom Scrollbar */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--text-muted);
}

/* Firefox-style thin scrollbars on every scroll container */
.sidebar-content,
.modal-body,
#search-results,
#toolbar-search-results,
#bloodline-legend,
.dropdown-content {
  scrollbar-width: thin;
  scrollbar-color: var(--scroll-thumb) transparent;
}

/* Global interaction polish — keyboard users must always see where they are.
   !important so the ring beats every later equal-specificity box-shadow
   (.btn-primary, .save-chip, inputs…). Nothing focusable lives on the
   canvas, so the tree-moving strip is unaffected. */
:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring) !important;
}

.btn:active,
.tab-btn:active {
  transform: translateY(0) scale(0.98);
}

input[type="radio"],
input[type="checkbox"] {
  accent-color: var(--accent-teal);
}

select option {
  background: var(--bg-secondary);
}

/* Icon-only toolbar buttons get a lightweight CSS tooltip */
[data-tip] {
  position: relative;
}

[data-tip]:hover::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: #0b101b;
  color: #e2e8f0;
  font-size: 0.72rem;
  padding: 4px 8px;
  border-radius: var(--r-sm);
  white-space: nowrap;
  border: 1px solid rgba(255, 255, 255, 0.1);
  z-index: 200;
  pointer-events: none;
}

/* Viewport Area */
.main-viewport {
  flex: 1;
  position: relative;
  overflow: hidden;
  height: 100%;
}

/* Top Toolbar */
.toolbar {
  position: absolute;
  top: 20px;
  left: 20px;
  right: 20px;
  z-index: 100; /* Stacks on top of viewport canvas */
  pointer-events: none; /* Let clicks pass through to canvas except buttons */
}

.toolbar-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  pointer-events: auto; /* Re-enable clicks */
  background: var(--glass-bg);
  /* No backdrop-filter: it sits over the pannable canvas (perf guardrail);
     the near-opaque --glass-bg supplies the glass look on its own */
  border: 1px solid var(--glass-border);
  padding: 8px 14px;
  gap: 12px;
  border-radius: var(--r-lg);
  box-shadow: 0 10px 30px rgba(15, 23, 42, 0.1);
}

.tool-group {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

#tree-status {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 230px;
}

.tool-divider {
  width: 1px;
  height: 26px;
  background: linear-gradient(transparent, var(--divider), transparent);
  margin: 0 8px;
}

/* Buttons — 4 variants: secondary (base), primary, ghost-ish icon, danger */
.btn {
  background-color: var(--btn-bg);
  border: 1px solid var(--btn-border);
  color: var(--text-primary);
  padding: 8px 14px;
  border-radius: var(--radius-control);
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 500;
  min-height: 36px;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: background-color var(--transition), border-color var(--transition), box-shadow var(--transition), transform var(--transition);
}

.btn:hover {
  background-color: var(--btn-hover-bg);
  border-color: var(--btn-hover-border);
  transform: translateY(-1px);
}

.btn-primary {
  background: linear-gradient(135deg, var(--primary), var(--primary-hover));
  border: none;
  color: #ffffff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 2px 8px rgba(var(--accent-rgb), 0.25);
}

.btn-primary:hover {
  background: var(--primary-hover);
  box-shadow: 0 0 10px rgba(var(--accent-rgb), 0.3);
}

.btn-danger {
  background-color: var(--danger-bg);
  border: 1px solid var(--danger-border);
  color: var(--danger-fg);
}

.btn-danger:hover {
  background-color: var(--danger-hover-bg);
  border-color: var(--danger-hover-border);
}

/* Calm destructive controls — delete must never be the loudest thing on
   screen. Both actions still confirm() before doing anything. */

/* Toolbar "Clear tree" trash: quiet ghost icon, only turns red on hover */
#btn-reset {
  background: none;
  border-color: transparent;
  color: var(--text-muted);
}

#btn-reset:hover {
  background: rgba(220, 38, 38, 0.08);
  border-color: rgba(220, 38, 38, 0.35);
  color: var(--danger-ink);
}

/* Sidebar "Delete Family Member": subtle danger — surface bg, red text,
   the border only reddens on hover */
#delete-person-btn {
  background: var(--surface);
  border: 1px solid var(--border-color);
  color: var(--danger-ink);
}

#delete-person-btn:hover {
  background: rgba(220, 38, 38, 0.06);
  border-color: var(--danger-ink);
}

.btn-icon {
  width: 36px;
  height: 36px;
  padding: 0;
  justify-content: center;
  border-radius: var(--r-md);
}

.zoom-indicator {
  font-size: 0.8125rem;
  color: var(--text-secondary);
  font-weight: 600;
  min-width: 48px;
  text-align: center;
}

/* Zoom controls grouped in one pill */
.zoom-cluster {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--pill-bg);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  padding: 2px;
}

.zoom-cluster .btn-icon {
  width: 30px;
  height: 30px;
  min-height: 0;
  border: none;
  background: transparent;
  border-radius: 999px;
}

.zoom-cluster .btn-icon:hover {
  background: var(--hover-tint);
}

/* Dropdown styling */
.dropdown {
  position: relative;
  display: inline-block;
}

.dropdown-content {
  display: none;
  position: absolute;
  inset-inline-end: 0; /* logical — lands on the correct side in RTL */
  top: calc(100% + 8px);
  background-color: var(--bg-secondary);
  min-width: 160px;
  box-shadow: var(--shadow-pop);
  border-radius: var(--r-lg);
  border: 1px solid var(--border-color);
  padding: 4px;
  z-index: 100;
  overflow: hidden;
}

.dropdown-content a, .dropdown-content label {
  color: var(--text-primary);
  padding: 10px 16px;
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.875rem;
  cursor: pointer;
  border-radius: var(--r-sm);
  transition: background-color var(--transition-speed) ease;
}

.dropdown-content a:hover, .dropdown-content label:hover {
  background-color: var(--hover-tint);
}

.dropdown.open .dropdown-content {
  display: block;
}

/* One-shot open animation for menus & search result panels */
@keyframes menuIn {
  from { opacity: 0; transform: translateY(-4px); }
}

.dropdown.open .dropdown-content,
#toolbar-search-results,
#search-results {
  animation: menuIn 0.12s ease-out;
}

.dropdown .fa-chevron-down {
  transition: transform 0.2s;
}

.dropdown.open .fa-chevron-down {
  transform: rotate(180deg);
}

/* Canvas Viewport — light "paper" workspace so the dark cards pop */
#canvas-viewport {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  background-color: var(--viewport-bg);
  z-index: 1; /* Stacks behind floating toolbar */
  touch-action: none; /* Enables pointer-based pan & pinch on touchscreens */
  cursor: grab;
}

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

/* Soft top shading over the workspace */
#canvas-viewport::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 90% 55% at 50% 0%, rgba(15, 23, 42, 0.05), transparent 65%);
  pointer-events: none;
  z-index: 3;
}

/* Pannable/Zoomable Canvas Container */
#canvas-container {
  position: absolute;
  transform-origin: 0 0;
  width: 40000px;
  height: 40000px;
  top: 0;
  left: 0;
  background-color: var(--canvas-bg);
  background-image: radial-gradient(circle, var(--canvas-dot) 1px, transparent 1px);
  background-size: 24px 24px;
  background-position: 0 0;
  pointer-events: auto;
}

#canvas-container.smooth {
  transition: transform 0.35s ease;
}

/* SVG Connections Overlay */
#connections-svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1;
  transition: opacity 0.2s ease;
}

/* ------------------------------------------------------------------------
   Connection lines. The per-branch bloodline colors (.bl-* / .arrow-bl-*
   classes, plus their dark-theme chip overrides) are NOT in this file:
   app.js generates and injects them into <head> from its BLOODLINES array
   — single source of truth. Only the neutral base strokes live here.
   ------------------------------------------------------------------------ */
.spouse-line {
  stroke: var(--spouse-line);
  stroke-width: 2;
  stroke-dasharray: 3 5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.8;
  fill: none;
}

/* Long-distance marriage arcs fade into the background until relevant */
.spouse-line.far {
  opacity: 0.45;
}

.parent-child-line {
  stroke: #64748b;
  stroke-width: 2.25;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.9;
  fill: none;
}

.corner-circle {
  fill: #64748b;
  stroke: var(--canvas-bg);
  stroke-width: 1.5;
}

/* Legend hover: dim every line except the hovered branch's */
body.legend-dim .parent-child-line {
  opacity: 0.22;
}

body.legend-dim .parent-child-line.hl {
  opacity: 1;
}

/* Dark-canvas themes: bright `chip` variants replace the dark inks */
body[data-theme="ocean"] .parent-child-line,
body[data-theme="forest"] .parent-child-line,
body[data-theme="royal"] .parent-child-line,
body[data-theme="crimson"] .parent-child-line { stroke: #94a3b8; }

body[data-theme="ocean"] .corner-circle,
body[data-theme="forest"] .corner-circle,
body[data-theme="royal"] .corner-circle,
body[data-theme="crimson"] .corner-circle { fill: #94a3b8; }

/* Spouse-line highlight: dark slate ink is for the light canvas only —
   on dark canvases the highlight must be brighter than resting state */
body[data-theme="ocean"] .spouse-line.hl,
body[data-theme="forest"] .spouse-line.hl,
body[data-theme="royal"] .spouse-line.hl,
body[data-theme="crimson"] .spouse-line.hl { stroke: #cbd5e1; }

/* ------------------------------------------------------------------------
   Dark-canvas themes: re-point every chrome token the light base owns back
   to the original dark recipes. themes.js (injected into <head> AFTER this
   sheet) then layers its per-theme hexes (--bg-*, --text-*, glass, cards,
   inputs, buttons, overlay) on top — so no light value can bleed through.
   ------------------------------------------------------------------------ */
body[data-theme="ocean"],
body[data-theme="forest"],
body[data-theme="royal"],
body[data-theme="crimson"] {
  --surface: var(--bg-secondary);
  --head-tint: rgba(15, 23, 42, 0.25);
  --hover-tint: rgba(255, 255, 255, 0.06);
  --chip-bg: rgba(255, 255, 255, 0.03);
  --panel-tint: rgba(15, 23, 42, 0.25);
  --pill-bg: rgba(15, 23, 42, 0.45);
  --row-line: rgba(255, 255, 255, 0.05);
  --track-tint: rgba(255, 255, 255, 0.08);
  --divider: rgba(255, 255, 255, 0.14);
  --scroll-thumb: var(--bg-tertiary);
  --btn-bg: var(--bg-tertiary);
  --btn-border: var(--border-color);
  --btn-hover-bg: #475569;
  --btn-hover-border: rgba(255, 255, 255, 0.2);
  --input-bg: rgba(15, 23, 42, 0.4);
  --input-border: var(--border-color);
  --input-focus-bg: rgba(15, 23, 42, 0.6);
  --input-focus-shadow: 0 0 5px rgba(var(--accent-rgb), 0.2);
  --card-border: rgba(2, 6, 15, 0.85);
  --avatar-bg: #273245;
  --avatar-ink: var(--text-primary);
  --panel-solid: rgba(17, 26, 40, 0.92);
  --shadow-pop: 0 14px 34px rgba(0, 0, 0, 0.45), 0 2px 8px rgba(0, 0, 0, 0.3);
  --shadow-card: 0 6px 16px rgba(0, 0, 0, 0.32);
  --shadow-card-hover: 0 10px 24px rgba(0, 0, 0, 0.42);
  --toast-bg: rgba(17, 26, 40, 0.94);
  --toast-border: rgba(255, 255, 255, 0.12);
  --ok-ink: #34d399;
  --warn-ink: #fbbf24;
  --danger-ink: #f87171;
  --danger-bg: rgba(239, 68, 68, 0.15);
  --danger-fg: #f87171;
  --danger-border: rgba(239, 68, 68, 0.3);
  --danger-hover-bg: rgba(239, 68, 68, 0.3);
  --danger-hover-border: rgba(239, 68, 68, 0.5);
  --primary-soft: rgba(var(--accent-rgb), 0.15);
  --focus-ring: 0 0 0 2px var(--bg-secondary), 0 0 0 4px var(--accent-teal);
}

/* Bloodline colour legend (bottom-left of the canvas) */
#bloodline-legend {
  position: absolute;
  left: 20px;
  bottom: 20px;
  z-index: 90;
  /* No backdrop-filter here: the legend sits over the pannable canvas and
     re-blurring the pixels behind it every frame tanks pan/zoom FPS.
     A near-opaque background keeps the premium glass look instead. */
  background: var(--panel-solid);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  padding: 10px 14px;
  max-height: 38vh;
  overflow-y: auto;
  box-shadow: 0 10px 30px rgba(15, 23, 42, 0.14);
  mask-image: linear-gradient(#000 85%, transparent);
  -webkit-mask-image: linear-gradient(#000 85%, transparent);
}

.legend-title {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-secondary);
  font-weight: 700;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.legend-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.8125rem;
  color: var(--text-primary);
  padding: 4px 2px;
  border-radius: var(--r-sm);
  cursor: pointer;
}

.legend-row:hover {
  background: var(--hover-tint);
}

.legend-chip {
  width: 18px;
  height: 6px;
  border-radius: 3px;
  flex-shrink: 0;
}

.legend-count {
  color: var(--text-muted);
  font-size: 0.72rem;
  margin-inline-start: auto;
  padding-inline-start: 8px;
}

/* Tasks tab */
.task-section {
  margin-bottom: 18px;
}

.task-section h5 {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.task-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--chip-bg);
  border: 1px solid var(--border-color);
  border-inline-start: 3px solid #38bdf8; /* accent hugs the reading edge in LTR and RTL */
  border-radius: var(--r-md);
  padding: 10px 12px;
  margin-bottom: 8px;
  transition: transform var(--transition-speed) ease;
}

.task-row:hover {
  transform: translateX(2px);
}

/* Category color on the reading edge (keyed off each section's heading icon) */
.task-section:has(> h5 .fa-triangle-exclamation) .task-row {
  border-inline-start-color: #f87171;
}

.task-section:has(> h5 .fa-link) .task-row {
  border-inline-start-color: #fbbf24;
}

.task-section:has(> h5 .fa-pen) .task-row {
  border-inline-start-color: #38bdf8;
}

.task-row > i {
  margin-top: 3px;
  font-size: 0.8125rem;
  flex-shrink: 0;
}

.task-text {
  flex: 1;
  font-size: 0.8125rem;
  color: var(--text-primary);
  line-height: 1.45;
}

.task-btn {
  padding: 4px 10px;
  font-size: 0.75rem;
  flex-shrink: 0;
}

.tasks-done {
  text-align: center;
  padding: 40px 16px;
  color: var(--text-secondary);
}

.tasks-done i {
  font-size: 2.5rem;
  color: var(--ok-ink);
  margin-bottom: 12px;
}

.tasks-done h3 {
  color: var(--text-primary);
  margin-bottom: 6px;
  font-size: 1.05rem;
}

.tasks-done p {
  font-size: 0.875rem;
  line-height: 1.5;
}

/* Highlighted lines for the hovered/selected person — keeps each line's
   bloodline colour, just thickens and lifts */
.parent-child-line.hl {
  stroke-width: 4;
  filter: drop-shadow(0 1px 2px rgba(15, 23, 42, 0.35));
}

.spouse-line.hl {
  stroke: #475569;
  stroke-width: 3;
  opacity: 1;
}

/* Family Member Cards — white surface, gender strip on the TOP edge
   (direction-neutral), bloodline underline on the BOTTOM edge */
.node-card {
  position: absolute;
  width: var(--card-width);
  height: var(--card-height);
  background: var(--surface);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-card);
  font-size: var(--fs, 14px); /* per-card scale set by JS; internals use em */
  padding: 0.65em;
  display: flex;
  align-items: center;
  gap: 0.8em;
  cursor: grab;
  user-select: none;
  z-index: 2;
  box-shadow: var(--shadow-card);
  touch-action: none;
  transition: border-color var(--transition-speed) ease, box-shadow var(--transition-speed) ease,
              transform 0.15s ease, left 0.35s ease, top 0.35s ease;
}

/* 4px gender strip on the top edge (a pseudo-element, not border-top, so
   theme border overrides can never swallow it). Flat fill — cheap to paint. */
.node-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 4px;
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  background: var(--gc, var(--unknown));
  pointer-events: none;
}

.node-card:active {
  cursor: grabbing;
}

.node-card.dragging {
  transition: border-color var(--transition-speed) ease, box-shadow var(--transition-speed) ease;
  transform: none;
  z-index: 5;
}

.node-card.male { --gc: var(--male); }
.node-card.female { --gc: var(--female); }
.node-card.other { --gc: var(--other); }
.node-card.unknown { --gc: var(--unknown); }

/* Hover: neutral lift — the accent ring is reserved for SELECTION */
.node-card:hover {
  border-color: var(--btn-hover-border);
  transform: translateY(-2px);
  box-shadow: var(--shadow-card-hover);
}

.node-card.selected {
  border-color: var(--accent-teal);
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.85), 0 0 0 7px rgba(var(--accent-rgb), 0.15), 0 12px 30px rgba(15, 23, 42, 0.18);
  transform: scale(1.08);
  z-index: 4;
}

.node-card.selected:hover {
  transform: scale(1.08) translateY(-1px);
}

.node-card.dragging,
.node-card.selected.dragging {
  transform: none;
}

/* Deceased: quiet the person, never the branch — the underline stays on */
.node-card.deceased .card-avatar {
  filter: grayscale(0.7);
  opacity: 0.85;
}

.node-card.deceased .card-name {
  opacity: 0.88; /* theme-safe muting (no hardcoded color) */
}

.node-card.deceased .card-flags img {
  filter: grayscale(0.55);
  opacity: 0.7;
}

/* Ghost cards: married-away members shown under their own parents.
   Click to jump to where they live with their spouse. */
.node-card.ghost {
  background: var(--ghost-bg);
  border: 1.5px dashed var(--ghost-border);
  box-shadow: none;
  padding: 0.4em 0.8em;
  cursor: pointer;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* Ghosts are quiet reference cards — no gender strip */
.node-card.ghost::before {
  display: none;
}

.node-card.ghost:hover {
  background: var(--surface);
  border-color: var(--accent-teal);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(15, 23, 42, 0.18);
}

/* On dark canvases a white hover would glare — soften it */
body[data-theme="ocean"] .node-card.ghost:hover,
body[data-theme="forest"] .node-card.ghost:hover,
body[data-theme="royal"] .node-card.ghost:hover,
body[data-theme="crimson"] .node-card.ghost:hover {
  background: rgba(148, 163, 184, 0.16);
  border-color: var(--accent-teal);
}

.node-card.ghost.selected {
  border-style: dashed;
  border-color: var(--accent-teal);
  box-shadow: 0 0 14px rgba(var(--accent-rgb), 0.35);
}

.ghost-inner {
  overflow: hidden;
  min-width: 0;
}

.ghost-name {
  font-size: 1em;
  font-weight: 600;
  color: var(--ghost-name);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ghost-hint {
  font-size: 0.82em;
  color: var(--accent-teal);
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 0.1em;
}

.node-card.ghost:hover .ghost-hint {
  text-decoration: underline;
}

/* Jump chip on a married-away person's real card -> their bloodline side */
.jump-chip {
  position: absolute;
  right: -9px;
  top: -9px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--bg-tertiary);
  border: 1px solid var(--accent-teal);
  color: var(--accent-teal);
  font-size: 10px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 6;
  transition: background-color var(--transition), color var(--transition), border-color var(--transition), transform var(--transition);
}

.jump-chip:hover {
  background: var(--accent-teal);
  color: #fff;
  transform: scale(1.15);
}

/* Bloodline underline: ties each card to its family's line colour.
   Full-width — it exactly mirrors the legend chips. */
.node-card::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 4px;
  border-radius: 0 0 var(--radius-card) var(--radius-card);
  background: var(--bl, transparent);
  opacity: 1;
  box-shadow: 0 0 6px -1px var(--bl, transparent);
  pointer-events: none;
}

/* Ghosts keep the underline too — it ties married-away members to their
   bloodline — but without the glow (they're light, quiet cards) */
.node-card.ghost::after {
  box-shadow: none;
  opacity: 0.9;
}

/* Card internals — sized in em so everything scales with the card.
   Branch ring is a box-shadow (never a border) so photos can't cover it:
   gender = left border, bloodline = avatar ring + underline. */
.card-avatar {
  width: var(--av, 44px);
  height: var(--av, 44px);
  border-radius: 50%;
  background: var(--avatar-bg);
  border: none;
  box-shadow: 0 0 0 2px var(--bl, #94a3b8);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: calc(var(--av, 44px) * 0.38);
  font-weight: 600;
  color: var(--avatar-ink);
  overflow: hidden;
  flex-shrink: 0;
}

.card-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.card-info {
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
  flex-grow: 1;
}

.card-name {
  font-size: 1em;
  font-weight: 600;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.card-dates {
  font-size: 0.82em;
  color: var(--text-secondary);
  margin-top: 0.15em;
}

.card-role {
  font-size: 0.72em;
  color: var(--accent-teal);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-top: 0.1em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Deceased Badge Styling — tightened: quieter chip, less vertical air */
.card-deceased-badge {
  font-size: 0.66em;
  padding: 0.08em 0.45em;
  border-radius: 4px;
  background: rgba(148, 163, 184, 0.12);
  border: 1px solid rgba(148, 163, 184, 0.28);
  color: var(--text-secondary);
  letter-spacing: 0.02em;
  margin-top: 0.2em;
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  width: fit-content;
  white-space: nowrap;
}

.card-deceased-badge i {
  font-size: 0.85em !important;
}

/* Form Styles & Inputs */
.form-group {
  margin-bottom: 18px;
}

.form-group label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 6px;
}

.form-row {
  display: flex;
  gap: 12px;
}

.form-row .form-group {
  flex: 1;
}

input[type="text"], input[type="date"], select, textarea {
  width: 100%;
  background-color: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-control);
  color: var(--text-primary);
  padding: 9px 12px;
  font-size: 0.875rem;
  font-family: var(--font-family);
  transition: border-color var(--transition), box-shadow var(--transition), background-color var(--transition);
}

input[type="text"]:focus, input[type="date"]:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent-teal);
  box-shadow: var(--input-focus-shadow);
  background-color: var(--input-focus-bg);
}

textarea {
  resize: vertical;
  min-height: 80px;
}

/* Image Upload Widget */
.image-upload-wrapper {
  display: flex;
  align-items: center;
  gap: 16px;
}

.image-preview {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background-color: var(--chip-bg);
  border: 2px dashed var(--input-border);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 1.5rem;
  color: var(--text-muted);
  overflow: hidden;
  flex-shrink: 0;
}

.image-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-upload-btn {
  position: relative;
  overflow: hidden;
}

.image-upload-btn input[type="file"] {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 100%;
  min-height: 100%;
  font-size: 100px;
  text-align: right;
  opacity: 0;
  outline: none;
  cursor: pointer;
  display: block;
}

/* Relationship Quick Builder panel */
.relations-panel {
  background-color: var(--panel-tint);
  border: 1px solid var(--border-color);
  border-radius: var(--r-md);
  padding: 14px;
  margin-top: 12px; /* consistent 12px rhythm with the stats sections */
}

/* Kinship result panel eases in */
#kinship-result-container {
  animation: fadeUp 0.22s ease;
}

@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
}

.relations-panel h4 {
  font-size: 0.8125rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
  margin-bottom: 12px;
}

.relations-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px; /* matches .stat-tiles gap */
}

/* Quick-action buttons read as tidy equal segments */
.relations-grid .btn {
  justify-content: center;
  border-radius: var(--r-md);
}

/* Detail panel empty state */
.empty-panel-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px 20px;
  color: var(--text-secondary);
  height: 100%;
}

.empty-panel-state i {
  font-size: 2.4rem;
  color: var(--accent-teal);
  width: 88px;
  height: 88px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(var(--accent-rgb), 0.08);
  border: 1px solid rgba(var(--accent-rgb), 0.22);
  margin-bottom: 18px;
}

.empty-panel-state h3 {
  letter-spacing: -0.01em;
}

.empty-panel-state p {
  font-size: 0.875rem;
  margin-bottom: 18px;
  line-height: 1.5;
}

/* Modal Dialog */
.modal {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(15, 23, 42, 0.5); /* no backdrop-filter: overlays the canvas */
  z-index: 1000;
  justify-content: center;
  align-items: center;
  opacity: 0;
  transition: opacity 0.18s ease;
}

.modal.active {
  display: flex;
  opacity: 1;
}

.modal-content {
  background-color: var(--bg-secondary);
  border: 1px solid var(--glass-border);
  border-radius: 16px;
  width: 520px;
  max-width: 90%;
  box-shadow: 0 20px 50px rgba(15, 23, 42, 0.25);
  overflow: hidden;
  transform: scale(0.96) translateY(6px);
  transition: transform 0.18s ease;
}

.modal.active .modal-content {
  transform: scale(1) translateY(0);
}

.modal-header {
  padding: 16px 24px;
  border-bottom: 1px solid var(--border-color);
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: var(--head-tint);
}

.modal-header h3 {
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.modal-close {
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 1.25rem;
  cursor: pointer;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color var(--transition-speed) ease, background-color var(--transition-speed) ease;
}

.modal-close:hover {
  color: var(--text-primary);
  background: var(--hover-tint);
}

/* Add-method choice cards light up when picked */
.add-method-card:has(input:checked) {
  border-color: var(--accent-teal) !important;
  background: rgba(var(--accent-rgb), 0.08) !important;
}

.modal-body {
  padding: 24px;
  max-height: 70vh;
  overflow-y: auto;
}

.modal-body p {
  font-size: 0.9375rem;
  color: var(--text-secondary);
  line-height: 1.6;
  margin-bottom: 14px;
}

.modal-footer {
  padding: 16px 24px;
  border-top: 1px solid var(--border-color);
  display: flex;
  justify-content: flex-end; /* flex handles RTL for free */
  gap: 12px;
  background-color: var(--head-tint);
}

/* Help modal specific styles */
.help-section {
  margin-bottom: 20px;
}

.help-section h4 {
  font-size: 0.9375rem;
  color: var(--accent-teal);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.help-section ul {
  list-style-type: none;
  padding-inline-start: 4px;
}

.help-section li {
  font-size: 0.875rem;
  color: var(--text-secondary);
  margin-bottom: 6px;
  line-height: 1.4;
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.help-section li::before {
  content: "•";
  color: var(--text-muted);
}

/* ============================== Phones ============================== */
@media (max-width: 700px) {
  /* Sidebar becomes a slide-in overlay */
  #sidebar {
    position: absolute;
    top: 0;
    bottom: 0;
    inset-inline-start: 0;
    height: 100%;
    width: min(86vw, 340px);
    min-width: 0;
    z-index: 400;
    transition: transform 0.28s ease;
    box-shadow: 0 0 44px rgba(15, 23, 42, 0.3); /* symmetric — RTL-safe */
  }

  #sidebar.collapsed {
    margin-inline-start: 0;
    transform: translateX(-104%);
  }

  /* Compact toolbar: icons only, horizontally scrollable */
  .toolbar {
    top: 10px;
    left: 10px;
    right: 10px;
  }

  .toolbar-inner {
    padding: 7px 10px;
    gap: 10px;
    overflow-x: auto;
    scrollbar-width: none;
    justify-content: flex-start; /* one scrollable row, no squeezing */
  }

  .toolbar-inner::-webkit-scrollbar {
    display: none;
  }

  .toolbar-inner .tool-group {
    flex-shrink: 0;
    min-width: auto;
  }

  .toolbar-inner .btn {
    font-size: 0; /* hides button text… */
    padding: 8px;
    flex-shrink: 0;
  }

  .toolbar-inner .btn i {
    font-size: 0.875rem; /* …but keeps the icons */
  }

  #tree-status {
    display: none;
  }

  .tool-divider {
    margin: 0 2px;
  }

  .zoom-indicator {
    min-width: 38px;
    font-size: 0.75rem;
  }

  #toolbar-search-input {
    width: 96px;
    font-size: 0.8125rem;
  }

  #toolbar-search-input:focus {
    width: 150px;
  }

  /* (#toolbar-search-results phone override lives in the trailing
     max-width:700px block after its base rule, so it wins the cascade.) */

  /* Less chrome on a small screen */
  #bloodline-legend {
    display: none !important;
  }

  #shajarah-minimap {
    width: 138px !important;
    right: 10px !important;
    bottom: 10px !important;
    padding: 6px 8px 8px !important;
  }

  #shajarah-timeline {
    width: min(86vw, 320px) !important;
    right: 10px !important;
  }

  .modal-content {
    width: 94%;
  }

  /* Bigger touch targets */
  .jump-chip {
    width: 27px;
    height: 27px;
    font-size: 12px;
    right: -11px;
    top: -11px;
  }

  .toolbar-inner {
    border-radius: 12px;
  }

  .zoom-cluster .btn-icon {
    width: 32px;
    height: 32px;
  }
}

/* Hotkey tag styles */
.key-tag {
  background-color: var(--bg-tertiary);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 0.75rem;
  font-family: monospace;
  font-weight: bold;
}

/* Toolbar search */
#toolbar-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  background: var(--pill-bg);
  border: 1px solid var(--border-color);
  border-radius: 9px;
  padding: 6px 10px;
}

#toolbar-search > i {
  color: var(--text-muted);
  font-size: 0.75rem;
  flex-shrink: 0;
}

#toolbar-search-input {
  background: none;
  border: none;
  outline: none;
  color: var(--text-primary);
  font-size: 0.8125rem;
  font-family: var(--font-family);
  width: 150px;
  padding: 0;
  transition: width 0.2s ease;
}

#toolbar-search-input:focus {
  width: 210px;
}

#toolbar-search-results {
  position: absolute;
  top: calc(100% + 8px);
  inset-inline-start: 0;
  min-width: 240px;
  max-height: 300px;
  overflow-y: auto;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 10px;
  box-shadow: var(--shadow-pop);
  z-index: 300;
}

/* Save status chip */
.save-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 11px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  border: 1px solid var(--border-color);
  background: var(--pill-bg);
  color: var(--text-secondary);
  white-space: nowrap;
  flex-shrink: 0;
  cursor: default;
}

.save-chip.ok {
  color: var(--ok-ink);
  border-color: rgba(16, 185, 129, 0.4);
}

.save-chip.ok i {
  font-size: 0.7rem;
}

/* View-only devices never show save plumbing */
body.edit-locked .save-chip {
  display: none !important;
}

.save-chip.bad {
  color: var(--danger-ink);
  border-color: rgba(239, 68, 68, 0.6);
  background: rgba(239, 68, 68, 0.12);
  animation: savePulse 1.6s ease infinite;
}

@keyframes savePulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
  50% { box-shadow: 0 0 10px 1px rgba(239, 68, 68, 0.35); }
}

@media (max-width: 700px) {
  .save-chip span { display: none; } /* icon-only on phones */
}

/* Toast notifications */
#shajarah-toast {
  position: fixed;
  bottom: calc(26px + env(safe-area-inset-bottom, 0px));
  left: 50%;
  transform: translate(-50%, 14px);
  background: var(--toast-bg); /* no backdrop-filter: floats over the canvas */
  border: 1px solid var(--toast-border);
  color: var(--text-primary);
  padding: 11px 20px;
  border-radius: 12px;
  box-shadow: var(--shadow-pop);
  font-size: 0.8125rem;
  z-index: 2000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
  max-width: 86vw;
  text-align: center;
}

#shajarah-toast.visible {
  opacity: 1;
  transform: translate(-50%, 0);
}

#shajarah-toast.success {
  border-color: rgba(var(--accent-rgb), 0.55);
}

#shajarah-toast.error {
  border-color: rgba(239, 68, 68, 0.55);
}

/* Edit lock: view-only mode hides everything that changes the tree */
#btn-lock.locked-state {
  border-color: rgba(217, 119, 6, 0.45);
  color: var(--warn-ink);
}

body.edit-locked #btn-add-person,
body.edit-locked #btn-layout,
body.edit-locked #btn-undo,
body.edit-locked #btn-redo,
body.edit-locked #btn-reset,
body.edit-locked #delete-person-btn,
body.edit-locked #quick-actions-panel,
body.edit-locked .relation-chip [data-action="unlink"],
body.edit-locked .task-btn[data-action="task-link-children"],
body.edit-locked .image-upload-btn,
body.edit-locked #remove-photo-btn,
body.edit-locked .dropdown-content label,
body.edit-locked #add-first-btn {
  display: none !important;
}

/* Lock banner: tells the user WHY things are missing + how to unlock */
#lock-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  background: linear-gradient(135deg, rgba(251, 191, 36, 0.12), rgba(251, 191, 36, 0.05));
  border: 1px solid rgba(251, 191, 36, 0.35);
  border-inline-start: 3px solid #fbbf24;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  border-radius: var(--r-md);
  padding: 10px 12px;
  margin-bottom: 16px;
  font-size: 0.8125rem;
  color: var(--text-primary);
}

#lock-banner > i {
  color: var(--warn-ink);
  flex-shrink: 0;
  font-size: 1rem;
}

#lock-banner span {
  flex: 1;
  line-height: 1.35;
}

#lock-banner .btn {
  padding: 5px 12px;
  font-size: 0.75rem;
  flex-shrink: 0;
}

/* Phone tweaks for the banner + toast + toolbar search results (must sit
   AFTER their base rules so the equal-specificity overrides win the cascade) */
@media (max-width: 700px) {
  #lock-banner {
    font-size: 0.78rem;
  }

  #shajarah-toast {
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  }

  /* Escape the toolbar's overflow-x:auto clipping: full-width fixed panel
     below the toolbar. Requires .toolbar-inner to have NO residual transform
     (its entrance animation fills backwards, not forwards), otherwise the
     toolbar becomes the containing block for this fixed panel. */
  #toolbar-search-results {
    position: fixed;
    left: 12px;
    right: 12px;
    top: 64px;
    min-width: 0;
  }
}

/* Search results styles */
.search-result-item {
  padding: 8px 10px;
  font-size: 0.85rem;
  cursor: pointer;
  border-inline-start: 3px solid transparent;
  border-radius: var(--r-sm);
  transition: background-color var(--transition-speed) ease, border-color var(--transition-speed) ease;
}

.search-result-item:hover {
  border-inline-start-color: var(--accent-teal);
  background: var(--hover-tint);
}

.search-result-item mark {
  background: rgba(var(--accent-rgb), 0.25);
  color: inherit;
  border-radius: 2px;
}

/* Unlock modal */
.unlock-input {
  /* type="password" misses the input[type="text"] base recipe — restate it */
  width: 100%;
  background-color: var(--input-bg);
  border: 1px solid var(--input-border);
  border-radius: var(--radius-control);
  color: var(--text-primary);
  font-family: var(--font-family);
  transition: border-color var(--transition-speed) ease, box-shadow var(--transition-speed) ease;
  text-align: center;
  font-size: 1.25rem !important;
  letter-spacing: 0.35em;
  font-weight: 700;
  padding: 12px !important;
}

.unlock-input:focus {
  outline: none;
  border-color: var(--accent-teal);
  box-shadow: var(--input-focus-shadow);
  background-color: var(--input-focus-bg);
}

.unlock-error {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--danger-ink);
  font-size: 0.8125rem;
  margin-top: 4px;
}

.unlock-input.shake {
  animation: unlockShake 0.3s ease;
}

@keyframes unlockShake {
  25% { transform: translateX(-5px); }
  50% { transform: translateX(5px); }
  75% { transform: translateX(-3px); }
}

/* Bulk-children rows in the add-relative modal */
.child-row {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
  align-items: center;
}

.child-row .child-first {
  flex: 1;
}

.child-row .child-gender {
  width: 92px;
  flex-shrink: 0;
}

.child-row .child-remove {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  color: var(--text-muted);
}

.child-row .child-remove:hover {
  color: var(--danger-ink);
}

/* Relationship chips in the sidebar */
.relation-chip {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--chip-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--r-sm);
  padding: 6px 12px;
  margin-bottom: 6px;
}

.relation-chip-name {
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: underline;
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Card flags: their own column on the right edge, stacked vertically */
.card-flags {
  display: flex;
  flex-direction: column;
  gap: 0.3em;
  flex-shrink: 0;
  align-self: flex-start;
  padding-top: 0.25em;
}

.card-flags img {
  width: 1.5em;
  height: 1.05em;
  border-radius: 2px;
  object-fit: cover;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.25);
  border: 1px solid rgba(15, 23, 42, 0.15);
  opacity: 0.9;
}

/* ------------------------------------------------------------------------
   Stats tab dashboard
   ------------------------------------------------------------------------ */
.stat-tiles {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.stat-tile {
  background: var(--chip-bg);
  border: 1px solid var(--border-color);
  border-radius: var(--r-md);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.stat-tile-num {
  font-size: 1.4rem;
  font-weight: 800;
  color: var(--text-primary);
  line-height: 1.15;
}

#stat-total {
  color: var(--accent-teal);
}

.stat-tile-caption {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-secondary);
}

.stat-section h3 {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--accent-teal);
  margin: 18px 0 8px;
}

.stat-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 2px;
  border-bottom: 1px solid var(--row-line);
  font-size: 0.875rem;
}

.stat-row .stat-label {
  color: var(--text-secondary);
  white-space: nowrap;
}

.stat-row .stat-value {
  font-weight: 700;
  color: var(--text-primary);
  text-align: end;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.stat-note {
  font-size: 0.7rem;
  color: var(--text-muted);
  font-style: italic;
  font-weight: 400;
  margin-inline-start: 4px;
}

.stat-bar {
  height: 6px;
  border-radius: 3px;
  background: var(--track-tint);
  overflow: hidden;
  margin: 6px 0 4px;
}

.stat-bar-fill {
  display: block;
  height: 100%;
  background: var(--accent-teal);
  border-radius: 3px;
  transition: width 0.4s ease;
}

/* Gender distribution (kept inside Family & Marriage) */
.stat-gender-wrap {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--row-line);
}

.stat-gender-title {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--text-secondary);
  margin-bottom: 8px;
}

#stat-gender-bar {
  display: flex;
  height: 8px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--bg-tertiary);
}

#stat-gender-legend {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 12px;
}

/* ------------------------------------------------------------------------
   Movement paint-strip — body.tree-moving is set by app.js the moment a
   pan/zoom/pinch starts and removed ~180ms after the last movement tick.
   While it's on, the expensive per-frame paint (card shadows, underline
   glow, selection halo, the 40000px dot grid) is stripped so every frame
   is a cheap composite. Bands, labels and connection lines stay visible —
   they're flat fills and part of the tree's identity.
   !important is required: themes.js injects per-theme .node-card.selected /
   #canvas-container rules into <head> AFTER this stylesheet, and they would
   otherwise out-rank these interaction-state rules. */
body.tree-moving #canvas-container {
  background-image: none !important; /* dot grid off while moving */
}

body.tree-moving .node-card {
  box-shadow: none !important;
  transition: none !important; /* no scale/left/top tweens mid-pan */
  animation: none !important;
}

body.tree-moving .node-card::after {
  box-shadow: none !important; /* underline glow off; the 4px colour stays */
}

body.tree-moving .node-card.selected {
  /* Selection stays readable as a plain 2px ring — just no 7px halo or
     drop shadow while the canvas is in motion */
  box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.85) !important;
}

body.tree-moving .toolbar-inner,
body.tree-moving #sidebar {
  /* Guarantee zero animation cost mid-pan. Duration-zeroing (instead of
     animation: none) finishes the entrance instantly WITHOUT cancelling it,
     so it can never replay when the class comes off after the pan. */
  animation-duration: 0s !important;
  animation-delay: 0s !important;
}

/* ------------------------------------------------------------------------
   One-time chrome entrance (toolbar + sidebar only — never .node-card,
   never legend/minimap which appear later via JS). Transform+opacity only,
   runs once on load. #sidebar fills backwards-only: a forwards fill would
   pin transform: translateX(0) forever and break the phone slide-out
   (#sidebar.collapsed relies on transform). */
@keyframes chromeIn {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes chromeInLeft {
  from { opacity: 0; transform: translateX(-14px); }
  to   { opacity: 1; transform: translateX(0); }
}

.toolbar-inner {
  /* backwards-only fill: a forwards fill would pin a non-none transform
     forever, turning .toolbar-inner into the containing block for
     position:fixed descendants (the phone #toolbar-search-results panel)
     and clipping them with the toolbar's overflow-x. */
  animation: chromeIn 0.45s cubic-bezier(0.22, 1, 0.36, 1) backwards;
}

#sidebar {
  animation: chromeInLeft 0.45s cubic-bezier(0.22, 1, 0.36, 1) backwards;
}

/* Phones: no sidebar entrance. It loads collapsed there, and while the
   animation runs its transform would override the .collapsed translateX,
   flashing the full sidebar over the tree before snapping out. The mobile
   slide-in transition already provides the polish. (Must sit AFTER the
   #sidebar entrance rule above to win the equal-specificity cascade.) */
@media (max-width: 700px) {
  #sidebar {
    animation: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .toolbar-inner,
  #sidebar {
    animation: none;
  }
}

/* ========================================================================
   i18n: language toggle, Pashto typography, RTL overrides
   Everything below is appended LAST so equal-specificity overrides win the
   cascade. [dir="rtl"] matches the attribute i18n.js sets on <html>.
   The tree canvas (#canvas-viewport, minimap, generation labels) carries
   dir="ltr" and is deliberately untouched — geometry is identical in both
   languages.
   ======================================================================== */

/* ---- Language toggle: segmented pill, centered in the toolbar --------- */
#lang-toggle {
  display: flex;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
  align-self: center;
  pointer-events: auto; /* .toolbar wrapper has pointer-events: none */
  background: var(--pill-bg);
  border: 1px solid var(--border-color);
  border-radius: 999px;
  padding: 3px;
}

.lang-btn {
  background: none;
  border: none;
  color: var(--text-secondary);
  font-family: var(--font-family);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  padding: 5px 10px;
  border-radius: 999px;
  transition: color var(--transition-speed) ease, background-color var(--transition-speed) ease;
}

.lang-btn:hover {
  color: var(--text-primary);
  background: var(--hover-tint);
}

.lang-btn.active {
  color: var(--accent-teal);
  background: rgba(var(--accent-rgb), 0.12);
  box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), 0.3);
}

.lang-btn.active:hover {
  background: rgba(var(--accent-rgb), 0.16);
}

.lang-sep {
  color: var(--text-muted);
  opacity: 0.55;
  font-size: 0.75rem;
  user-select: none;
}

/* ---- Pashto typography: Arabic script wants more leading --------------
   Glyphs come from the local 'Noto Naskh Arabic' face: it sits first in
   --font-family with an Arabic-only unicode-range, so it serves Arabic
   script everywhere (chrome AND cards) while Latin stays on the system
   stack. Leading rules are scoped to chrome containers only — card
   internals inherit nothing here, so canvas geometry stays identical. */

/* Arabic script reads better ~5% larger in the same slot (rem-based chrome
   scales; cards use px/em via --fs, so the canvas is untouched) */
html[lang="ps"] {
  font-size: 105%;
}

[lang="ps"] #sidebar,
[lang="ps"] .toolbar,
[lang="ps"] .modal,
[lang="ps"] #shajarah-toast,
[lang="ps"] #shajarah-timeline,
[lang="ps"] #theme-popover {
  line-height: 1.7;
}

[lang="ps"] .task-text {
  line-height: 1.7;
}

[lang="ps"] .help-section li {
  line-height: 1.7;
}

[lang="ps"] .modal-body p {
  line-height: 1.75;
}

[lang="ps"] #lock-banner span {
  line-height: 1.6;
}

/* NEVER track Arabic script — letter-spacing breaks letter joining.
   Kills the uppercase-header tracking (and any inherited tracking) on
   every slot that can hold Pashto text. */
[dir="rtl"] .logo,
[dir="rtl"] .legend-title,
[dir="rtl"] .task-section h5,
[dir="rtl"] .stat-section h3,
[dir="rtl"] .stat-tile-caption,
[dir="rtl"] .relations-panel h4,
[dir="rtl"] .card-role,
[dir="rtl"] .theme-pop-title,
[dir="rtl"] .empty-panel-state h3,
[dir="rtl"] .modal-header h3 {
  letter-spacing: 0;
}

/* ---- RTL overrides (desktop-first; phone block further down) ----------
   Only rules with physical properties that CANNOT be expressed logically
   (transforms, animations) remain here — everything else was migrated to
   logical properties above and mirrors automatically:
   sidebar seam/collapse margin, dropdown + search-results anchoring, the
   inline search-icon/flag/padding styles in index.html, logo subtitle
   alignment, and the unlock-modal icon margin. */

/* Sidebar lands on the RIGHT: flip only its entrance animation */
[dir="rtl"] #sidebar {
  animation-name: chromeInRight;
}

@keyframes chromeInRight {
  from { opacity: 0; transform: translateX(14px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* Task rows nudge INTO the reading direction on hover */
[dir="rtl"] .task-row:hover {
  transform: translateX(-2px);
}

/* themes.js injects `#theme-popover { right: 0 }` into <head> AFTER this
   sheet — under RTL its tool-group lands on the LEFT, so anchor left */
[dir="rtl"] #theme-popover {
  right: auto !important;
  left: 0 !important;
}

/* ---- Phones: RTL sidebar slides out to the RIGHT + toggle stays usable
   (must sit after the desktop RTL rules above to win the cascade) ------- */
@media (max-width: 700px) {
  [dir="rtl"] #sidebar {
    animation: none; /* keep the no-entrance phone behavior in RTL too */
  }

  [dir="rtl"] #sidebar.collapsed {
    transform: translateX(104%); /* transforms don't mirror — flip by hand */
  }

  /* Toggle scrolls with the icon toolbar; never squeezed out */
  #lang-toggle {
    flex-shrink: 0;
    padding: 2px;
  }

  .lang-btn {
    font-size: 0.78rem;
    padding: 6px 8px; /* keeps ~30px touch height */
  }
}

@media (prefers-reduced-motion: reduce) {
  [dir="rtl"] #sidebar {
    animation: none;
  }

  /* Disable decorative transforms/transitions. #canvas-container.smooth is
     deliberately untouched — app.js pan/zoom timing depends on it. */
  .node-card,
  .btn,
  .tab-btn,
  .lang-btn,
  .jump-chip,
  .task-row,
  .modal,
  .modal-content,
  .dropdown-content,
  #toolbar-search-results,
  #search-results,
  #shajarah-toast,
  #kinship-result-container,
  input, select, textarea {
    transition: none !important;
    animation: none !important;
  }

  .node-card:hover,
  .btn:hover,
  .task-row:hover,
  [dir="rtl"] .task-row:hover,
  .jump-chip:hover {
    transform: none;
  }
}
