:root {
  --bg: #1c1714;
  --surface: #2a2119;
  --surface-raised: #342820;
  --border: #4a3b30;
  --text: #f2e8dc;
  --text-muted: #b3a08f;
  --accent: #f2a53c;
  --accent-strong: #ffbf63;
  --on-accent: #241a0d;
  --valid: #74c07c;
  --valid-bg: rgba(116, 192, 124, 0.14);
  --invalid: #e2726a;
  --invalid-bg: rgba(226, 114, 106, 0.14);
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --shadow-card: 0 3px 10px rgba(0, 0, 0, 0.4);
  --font-display: ui-rounded, "SF Pro Rounded", system-ui, sans-serif;
  --font-body: system-ui, sans-serif;
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
  }
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
}

/* Pinned title, always visible. Centered on the page regardless of the
   New Puzzle button's width, via position:absolute on the button rather
   than flex space-between (which would center in the leftover space only). */
.app-header {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 14px 70px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  z-index: 10;
}

.app-header .title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 700;
  text-align: center;
}

.app-header .title .poop {
  color: var(--accent);
}

#new-puzzle-btn {
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  padding: 7px 14px;
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color 120ms ease, color 120ms ease, transform 80ms ease;
}

#new-puzzle-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

#new-puzzle-btn:active {
  transform: translateY(-50%) scale(0.96);
}

/* Celebration banner + undo toast: fixed, small, dismissible, never block
   the tree underneath. */
.notifications {
  position: fixed;
  top: 66px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: max-content;
  max-width: 90vw;
}

.celebration-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface-raised);
  border: 1px solid var(--accent);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  box-shadow: var(--shadow-card);
  font-weight: 600;
  color: var(--accent-strong);
}

.undo-toast {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--surface-raised);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 8px 12px;
  box-shadow: var(--shadow-card);
  font-size: 0.9rem;
}

.undo-toast .action-btn {
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: var(--radius-sm);
  padding: 3px 9px;
  font-size: 0.8rem;
  font-weight: 600;
}

.dismiss-btn {
  background: none;
  border: none;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
  color: inherit;
  opacity: 0.7;
  transition: opacity 120ms ease;
}

.dismiss-btn:hover {
  opacity: 1;
}

main {
  padding: 40px 20px;
}

/* Tree grows/scrolls independently of the fixed-width panel beside it, so a
   wide tree or a long abandoned list never widen the page as a whole. */
.workspace {
  display: flex;
  align-items: flex-start;
  gap: 24px;
}

.tree-area {
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* No fixed width: closed, this is just the toggle button's own width (minimal
   space); open, the list below sets a comfortable reading width. */
.abandoned-panel {
  flex: 0 0 auto;
  border-left: 1px solid var(--border);
  padding-left: 16px;
}

.abandoned-toggle {
  display: block;
  background: none;
  border: none;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  padding: 6px 4px;
  white-space: nowrap;
  border-radius: var(--radius-sm);
  transition: color 120ms ease;
}

.abandoned-toggle:hover {
  color: var(--text);
}

.abandoned-empty {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin: 8px 0 0;
}

.abandoned-list {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 200px;
}

/* Start-word entry form, shown when there's no puzzle yet */
.start-form {
  display: flex;
  gap: 8px;
  justify-content: safe center;
  margin-top: 60px;
}

.start-form input {
  font-size: 1.2rem;
  width: 11em;
  padding: 12px 14px;
}

/* --- Org-chart tree, built from nested <ul>/<li> --- */
/* DOM nesting mirrors data nesting, so these connector lines are drawn by
   plain box layout (border-top/border-left), no coordinates computed in JS. */

/* "safe center": center a row of siblings when it fits, but fall back to
   start-alignment the moment it doesn't. Plain "center" on an overflowing
   row pushes the overflow equally onto both sides — the right side is
   reachable by scrolling, but the left side lands at a negative offset an
   overflow:auto container can never scroll back to, permanently hiding
   part of the leftmost card (including its buttons). That was the actual
   cause of cards looking "clipped" on narrow screens, not their size. */
.tree, .tree ul {
  padding-top: 20px;
  position: relative;
  display: flex;
  justify-content: safe center;
}

.tree li {
  list-style-type: none;
  position: relative;
  padding: 20px 10px 0 10px;
  text-align: center;
}

.tree li::before,
.tree li::after {
  content: "";
  position: absolute;
  top: 0;
  right: 50%;
  width: 50%;
  height: 20px;
  border-top: 1px solid var(--border);
}

.tree li::after {
  right: auto;
  left: 50%;
  border-left: 1px solid var(--border);
}

.tree li:only-child::before,
.tree li:only-child::after {
  display: none;
}

.tree li:only-child {
  padding-top: 0;
}

.tree li:first-child::before,
.tree li:last-child::after {
  border: 0 none;
}

.tree li:last-child::before {
  border-right: 1px solid var(--border);
  border-radius: 0 6px 0 0;
}

.tree li:first-child::after {
  border-radius: 6px 0 0 0;
}

.tree ul ul::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 0;
  height: 20px;
  border-left: 1px solid var(--border);
}

/* --- Node boxes and their color-coded states --- */

.node-box {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-width: 120px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-card);
}

.node-box.valid {
  border-color: color-mix(in srgb, var(--valid) 55%, var(--border));
  background: linear-gradient(var(--valid-bg), var(--valid-bg)), var(--surface);
}

.node-box.valid .word {
  color: var(--valid);
}

.node-box.invalid {
  border-color: color-mix(in srgb, var(--invalid) 55%, var(--border));
  background: linear-gradient(var(--invalid-bg), var(--invalid-bg)), var(--surface);
}

.node-box.invalid .word {
  color: var(--invalid);
}

.node-box.stub {
  flex-direction: row;
  align-items: center;
  min-width: auto;
  padding: 8px 12px;
  gap: 10px;
  background: var(--surface);
  border-style: dashed;
  opacity: 0.75;
  box-shadow: none;
}

.node-box.stub .word {
  font-size: 0.95rem;
  color: var(--text-muted);
}

.node-box.goal {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent), var(--shadow-card);
}

.node-box.goal .word {
  color: var(--accent-strong);
}

.node-box .word {
  font-size: 1.15rem;
  letter-spacing: 0.05em;
  font-weight: 600;
}

.node-box .action-btn {
  font-size: 0.68rem;
  padding: 3px 8px;
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease, transform 80ms ease;
}

.node-box .action-btn:hover {
  color: var(--text);
  border-color: var(--text-muted);
}

.node-box .action-btn:active {
  transform: scale(0.96);
}

.node-box .add-child-form {
  display: flex;
  gap: 6px;
  margin-top: 4px;
}

.node-box .add-child-form input {
  width: 9.5em;
  padding: 10px 12px;
  font-size: 0.95rem;
}

.node-box .add-child-form button {
  font-size: 0.8rem;
  font-weight: 600;
  padding: 8px 14px;
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color 120ms ease, transform 80ms ease;
}

.node-box .add-child-form button:hover {
  background: var(--accent-strong);
}

.node-box .add-child-form button:active {
  transform: scale(0.96);
}

/* Mobile-only affordances: hidden on desktop by default, shown (and their
   desktop counterparts hidden) inside the mobile media query below. Same
   renderNode output either way — only visibility switches. */
.mobile-add-btn,
.mobile-add-bar {
  display: none;
}

/* Shared input treatment: generously sized past 4 uppercase letters plus
   padding, rather than tuned to "just fits" — that's the actual fix for the
   clipping that kept recurring. Placeholder stays lowercase (::placeholder
   overrides the uppercase transform applied to typed text). */
input[type="text"] {
  font-family: var(--font-body);
  background: var(--surface-raised);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  transition: border-color 120ms ease, box-shadow 120ms ease;
}

input[type="text"]::placeholder {
  text-transform: none;
  color: var(--text-muted);
  opacity: 0.8;
}

input[type="text"]:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}

button:focus-visible,
input[type="text"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* --- Mobile layout ---
   Same renderNode output as desktop; this breakpoint only changes which
   elements are visible and how the tree's own boxes are positioned relative
   to each other. Nothing here duplicates tree data or adds JS state. */
@media (max-width: 640px) {
  main {
    padding-bottom: 90px; /* clears the pinned bottom bar */
  }

  /* Tree area no longer needs its own horizontal scroll: siblings stack
     vertically instead of sitting side by side, so there's nothing to pan. */
  .tree-area {
    overflow-x: visible;
  }

  /* Stack panel below the tree instead of beside it. */
  .workspace {
    flex-direction: column;
  }

  .abandoned-panel {
    border-left: none;
    border-top: 1px solid var(--border);
    padding-left: 0;
    padding-top: 12px;
    margin-top: 12px;
    width: 100%;
  }

  .abandoned-list {
    width: 100%;
  }

  /* Turn off the row-based org-chart connectors (they draw horizontal
     branch lines that only make sense when siblings sit side by side). */
  .tree li::before,
  .tree li::after,
  .tree ul ul::before {
    content: none;
  }

  /* Siblings stack in a column instead of a row. align-items: stretch (the
     flex default) makes each card take the full row width. */
  .tree,
  .tree ul {
    flex-direction: column;
    align-items: stretch;
    padding-top: 0;
  }

  .tree li {
    padding: 0;
    margin-bottom: 12px;
    text-align: left;
  }

  /* Every nested <ul> is one generation of children — a left border plus
     indent reads as "these belong to the node above," and compounds
     naturally deeper into the tree since each level nests its own ul inside
     the previous one's li. ".tree ul" (descendant combinator) matches every
     children-list at every depth, but not .tree itself — the root's own
     list shouldn't be indented, since it has no parent to indent from. */
  .tree ul {
    margin: 8px 0 12px 16px;
    padding: 10px 0 0 16px;
    border-left: 2px solid var(--border);
  }

  .node-box {
    width: 100%;
  }

  /* Desktop's embedded per-node form is replaced by the "+ Add here" button
     below plus the single pinned bar at the bottom of the screen. */
  .node-box .add-child-form {
    display: none;
  }

  .mobile-add-btn {
    display: block;
    width: 100%;
    min-height: 40px;
    font-size: 0.85rem;
    font-weight: 600;
    background: transparent;
    color: var(--accent);
    border: 1px dashed var(--border);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease;
  }

  .mobile-add-btn:hover,
  .mobile-add-btn:active {
    border-color: var(--accent);
    background: var(--valid-bg);
  }

  /* Comfortable tap targets throughout, since these are the controls a
     finger (not a mouse) has to hit. */
  .node-box .action-btn {
    min-height: 36px;
    padding: 6px 12px;
    font-size: 0.75rem;
  }

  .node-box .word {
    font-size: 1.2rem;
  }

  .mobile-add-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
    background: var(--surface);
    border-top: 1px solid var(--border);
    box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.35);
  }

  .mobile-add-bar:empty {
    display: none;
  }

  .mobile-add-bar-label {
    font-size: 0.8rem;
    color: var(--text-muted);
  }

  .mobile-add-bar-form {
    display: flex;
    gap: 8px;
  }

  .mobile-add-bar-form input {
    flex: 1;
    min-height: 44px;
    font-size: 1rem;
    padding: 10px 12px;
  }

  .mobile-add-bar-form button {
    min-height: 44px;
    padding: 0 20px;
    font-size: 0.9rem;
    font-weight: 600;
    background: var(--accent);
    color: var(--on-accent);
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
  }
}
