:root {
  --ground: #eef3fa;        /* soft sky-white desk */
  --paper: #ffffff;
  --ink: #1e2b3c;
  --ink-soft: #66788f;
  --line: #dde5f0;
  --accent: #3b82c4;        /* friendly blue for primary actions */
  --accent-soft: #e4effa;
  --gold: #e0a52b;          /* achievements */
  --danger: #d0524e;
  --radius: 18px;
  font-family: "IBM Plex Sans Arabic", "Segoe UI", Tahoma, system-ui, sans-serif;
}

* { box-sizing: border-box; }

/* ───────────── Icon system ─────────────
   One stroked set on a 24×24 grid. Stroke inherits currentColor so an icon
   takes the colour of whatever button holds it, in either theme, with no
   per-icon rules. */
.sprite { display: none; }
.ic {
  width: 1.15em; height: 1.15em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.2em;
  pointer-events: none;
}
/* Only buttons that actually hold an icon become flex rows, so every other
   control on the page keeps exactly the layout it had before. */
.btn-ghost:has(.ic), .btn-primary:has(.ic), .chip:has(.ic), .mode-tab:has(.ic) {
  display: inline-flex; align-items: center; gap: 0.4rem;
}
.mnav { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.15rem; }
/* Short captions exist only for the narrow layout. */
.btn-short { display: none; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--ground);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.5;
}

body { display: flex; flex-direction: column; }

h1, h2 { margin: 0; font-weight: 600; }
h1 { font-size: 1.25rem; }
h2 { font-size: 1.05rem; }

/* ───────────── Night mode ───────────── */
:root[data-theme="dark"] {
  --ground: #141c27;
  --paper: #1c2635;
  --ink: #e8eef7;
  --ink-soft: #9fb0c6;
  --line: #2e3b50;
  --accent: #6aa7e6;
  --accent-soft: #24354d;
  --gold: #e8b74a;
}
/* Same "everything text-like" selector as the light theme, so a new field can
   never again inherit a white background here while its neighbours are dark. */
:root[data-theme="dark"] input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="submit"]):not([type="button"]),
:root[data-theme="dark"] textarea,
:root[data-theme="dark"] .tool, :root[data-theme="dark"] .chip, :root[data-theme="dark"] .library-open, :root[data-theme="dark"] .cal-menu {
  background: #111925; color: var(--ink); border-color: var(--line);
}
/* Placeholders were legible on white but nearly invisible on the dark field. */
:root[data-theme="dark"] input::placeholder,
:root[data-theme="dark"] textarea::placeholder { color: #7f8fa6; }

/*
 * Autofilled fields.
 *
 * When the browser fills a field from its saved data it paints its own
 * background, and `background` cannot override it — which is why the email
 * box stayed white in night mode while the fields beside it were dark. A
 * large inset shadow is the only way to repaint that area, and
 * -webkit-text-fill-color is the only way to recolour the text inside it.
 * The absurd transition delay stops the browser animating back to its own
 * colour a moment after filling.
 */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--ink);
  box-shadow: 0 0 0 1000px #fff inset;
  transition: background-color 600000s 0s, color 600000s 0s;
}
:root[data-theme="dark"] input:-webkit-autofill,
:root[data-theme="dark"] input:-webkit-autofill:hover,
:root[data-theme="dark"] input:-webkit-autofill:focus,
:root[data-theme="dark"] input:-webkit-autofill:active {
  box-shadow: 0 0 0 1000px #111925 inset;
}
/* The standard pseudo-class, which Firefox implements — the -webkit- one
   above does nothing there, so the field stayed white. */
input:autofill {
  background-color: #fff !important;
  color: var(--ink) !important;
  filter: none;
}
:root[data-theme="dark"] input:autofill {
  background-color: #111925 !important;
  color: var(--ink) !important;
}
/* Last resort: whatever the browser decides an autofilled email looks like,
   these win on specificity in the dark theme. */
:root[data-theme="dark"] .auth-form input,
:root[data-theme="dark"] .auth-form textarea {
  background-color: #111925;
  color: var(--ink);
  border-color: var(--line);
}
:root[data-theme="dark"] .msg.assistant { background: #26334a; }
:root[data-theme="dark"] .auth-dialog { background: var(--paper); }
:root[data-theme="dark"] .map-toolbar { background: rgba(28, 38, 53, 0.9); }
:root[data-theme="dark"] .board-stage[data-board="white"] { box-shadow: inset 0 0 0 1px var(--line); }
/* the mind map stays a white sheet in every theme */
.btn-ghost.icon { padding: 0.3rem 0.5rem; font-size: 1rem; line-height: 1; }

/* ───────────── Top bar and brand ───────────── */
.topbar {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  padding: 0.7rem 1.5rem;
  border-bottom: 1px solid var(--line);
}
.brand {
  display: flex; align-items: center; gap: 0.6rem;
  text-decoration: none; color: inherit; direction: ltr;
}
.brand-mark {
  flex: none; border-radius: 12px;
  transition: transform 0.18s ease;
}
.brand:hover .brand-mark { transform: rotate(-6deg) scale(1.04); }
.brand-text { display: flex; flex-direction: column; gap: 0.15rem; }
.brand-word {
  font-size: 1.3rem; font-weight: 600; line-height: 1;
  letter-spacing: -0.018em; color: var(--ink); white-space: nowrap;
}
.brand-tld { color: var(--accent); font-weight: 500; }
.brand-tagline {
  font-size: 0.68rem; font-weight: 500; line-height: 1;
  color: var(--ink-soft); white-space: nowrap;
}
.topbar-hint { margin: 0; color: var(--ink-soft); font-size: 0.85rem; flex: 1; }

/* ───────────── Language switcher ───────────── */
.lang-switch { position: relative; }
.lang-btn { display: inline-flex; align-items: center; gap: 0.35rem; padding: 0.3rem 0.55rem; }
.flag {
  width: 21px; height: 14px; flex: none;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12);
  display: block;
}
.lang-code { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.02em; }
.lang-menu {
  position: absolute; top: calc(100% + 0.4rem); inset-inline-end: 0; z-index: 40;
  min-width: 200px; margin: 0; padding: 0.3rem;
  list-style: none;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 12px 32px rgba(30, 43, 60, 0.18);
}
.lang-menu[hidden] { display: none; }
.lang-item {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.45rem 0.55rem; border-radius: 8px;
  color: var(--ink); text-decoration: none; font-size: 0.85rem;
}
.lang-item:hover { background: var(--accent-soft); color: var(--accent); }
.lang-item.current { font-weight: 600; }
.lang-item .tick { width: 1rem; height: 1rem; margin-inline-start: auto; color: var(--accent); }
.account { display: flex; align-items: center; gap: 0.5rem; }
.account-name { font-weight: 600; font-size: 0.9rem; }

/* ───────────── Footer ───────────── */
.footer {
  border-top: 1px solid var(--line);
  padding: 0.6rem 1.5rem;
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.25rem 1.5rem;
  font-size: 0.78rem; color: var(--ink-soft);
}
.footer p { margin: 0; }

/* ───────────── Board layout ───────────── */
.board {
  flex: 1;
  display: grid;
  /* Column widths live in variables so the edge handles can follow the panel
     borders as they collapse; a hidden panel becomes a 0-wide column rather
     than display:none, which would reshuffle the grid under the handles. */
  --col-todo: 300px;
  --col-chat: 340px;
  --board-pad: 1.5rem;
  grid-template-columns: var(--col-todo) 1fr var(--col-chat);
  gap: 1rem;
  padding: 1rem var(--board-pad) 1.5rem;
  min-height: 0;
  position: relative;
  direction: ltr;          /* fixed column order: to-do | map | chat */
  transition: grid-template-columns 0.22s ease;
}
/*
 * .board above is pinned to ltr so the columns keep their order in every
 * language. That would also flip the text inside them, so each panel takes its
 * direction back from the document -- which i18n sets per locale. Without this
 * a question mark, being a neutral character, lands at the wrong end of the
 * line: "Quais sao suas ?ideias hoje".
 */
.panel { direction: ltr; }
html[dir="rtl"] .panel { direction: rtl; }

/* Hidden side panels give their width back to the workspace. */
.board.hide-todo { --col-todo: 0px; }
.board.hide-chat { --col-chat: 0px; }
.board.hide-todo > .panel-todo,
.board.hide-chat > .panel-chat {
  padding: 0; border-width: 0; opacity: 0; pointer-events: none;
}

/* ───────────── Edge handles ───────────── */
.edge-tab {
  position: absolute;
  top: 30%;
  z-index: 5;
  writing-mode: vertical-rl;
  padding: 0.85rem 0.3rem;
  background: var(--paper);
  color: var(--ink-soft);
  border: 1px solid var(--line);
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(30, 43, 60, 0.12);
  transition: left 0.22s ease, right 0.22s ease, color 0.15s, border-color 0.15s;
}
.edge-tab:hover { color: var(--accent); border-color: var(--accent); }

/* rotate(180deg) reverses the reading direction of the vertical label; the
   standalone rotate/scale used by the click animation composes on top of it. */
.edge-tab-todo {
  left: calc(var(--board-pad) + var(--col-todo));
  transform: translateX(-50%) rotate(180deg);
  border-radius: 10px 0 0 10px;
}
.edge-tab-chat {
  right: calc(var(--board-pad) + var(--col-chat));
  transform: translateX(50%) rotate(180deg);
  border-radius: 0 10px 10px 0;
}
.edge-tab[aria-pressed="false"] { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }

/* Closed, the tab is no longer hanging off a panel — it is anchored to the
   outer edge instead, so the rounded side swaps to face the workspace. */
.board.hide-todo .edge-tab-todo { border-radius: 0 10px 10px 0; }
.board.hide-chat .edge-tab-chat { border-radius: 10px 0 0 10px; }

/* Spin-and-squeeze on click. Uses the standalone rotate/scale properties so the
   translateX that pins each tab to its border is left untouched. */
@keyframes edge-turn {
  0%   { rotate: 0deg;   scale: 1; }
  45%  { rotate: 180deg; scale: 0.82; }
  100% { rotate: 360deg; scale: 1; }
}
.edge-tab.turning { animation: edge-turn 0.5s cubic-bezier(0.4, 0, 0.2, 1); }


.panel {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.1rem;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  box-shadow: 0 6px 20px rgba(30, 43, 60, 0.05);
}
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.link-soft { font-size: 0.78rem; color: var(--accent); text-decoration: none; }
.link-soft:hover { text-decoration: underline; }
.link-soft[hidden] { display: none; }

/* welcome strip for guests */
.welcome {
  display: flex; align-items: center; gap: 1rem;
  margin: 0.9rem 1.5rem 0;
  padding: 0.7rem 1rem;
  background: var(--accent-soft); color: var(--ink);
  border-radius: 14px; font-size: 0.88rem;
}
.welcome p { margin: 0; flex: 1; }

/* ───────────── Buttons and inputs ───────────── */
button, input, textarea { font: inherit; color: inherit; }

.btn-primary {
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 10px;
  padding: 0.55rem 1rem;
  cursor: pointer;
}
.btn-primary:hover { background: #2f6fae; }
.btn-primary:disabled { opacity: 0.55; cursor: wait; }

.btn-ghost {
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.4rem 0.8rem;
  cursor: pointer;
  color: var(--ink-soft);
}
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn-ghost.small, .btn-primary.small { padding: 0.3rem 0.7rem; font-size: 0.8rem; }
.btn-ghost:disabled { opacity: 0.4; cursor: default; }

/* Every text-like field, described by what it is NOT. Listing types by name
   meant each new field had to be remembered — type="email" was missed and
   rendered white on the dark theme while its neighbours were dark. */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="submit"]):not([type="button"]),
textarea {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.55rem 0.75rem;
  background: #fff;
  color: var(--ink);
}
input:focus-visible, textarea:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ───────────── To-do panel ───────────── */
.add-box { margin: 0.9rem 0 0.75rem; padding: 0.6rem; background: var(--ground); border-radius: 14px; }
.add-row { display: flex; gap: 0.5rem; }
.add-schedule { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; flex-wrap: wrap; }
.add-schedule input[type="datetime-local"] { width: auto; flex: 1; padding: 0.35rem 0.6rem; font-size: 0.85rem; border-radius: 10px; }
.add-schedule input[hidden] { display: none; }
.chip {
  background: #fff; border: 1px solid var(--line); border-radius: 999px;
  padding: 0.3rem 0.75rem; font-size: 0.8rem; cursor: pointer; color: var(--ink-soft);
}
.chip:hover, .chip.active { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }

.todo-list { list-style: none; margin: 0; padding: 0; overflow-y: auto; }

.todo-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.25rem;
  border-bottom: 1px solid var(--line);
}
.todo-item:last-child { border-bottom: none; }
.todo-item input[type="checkbox"] {
  width: 22px; height: 22px;
  accent-color: var(--accent);
  cursor: pointer;
  flex-shrink: 0;
}
.todo-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; position: relative; }
.todo-item .title { word-break: break-word; cursor: text; border-radius: 6px; }
.todo-item .title:hover { background: var(--ground); }
.title-edit { padding: 0.25rem 0.5rem; font-size: 0.95rem; }
.due {
  align-self: flex-start;
  background: var(--accent-soft); color: var(--accent);
  border: none; border-radius: 999px; padding: 0.1rem 0.6rem;
  font-size: 0.74rem; cursor: pointer; font-weight: 500;
}
.due:hover { background: #d3e4f6; }
.due.overdue { background: #fbe4e3; color: var(--danger); }
.due.ghost { background: transparent; color: var(--ink-soft); opacity: 0; padding-inline: 0.2rem; }
.todo-item:hover .due.ghost, .todo-item:focus-within .due.ghost { opacity: 1; }
.due-inline { margin-top: 0.3rem; padding: 0.3rem 0.5rem; font-size: 0.82rem; width: auto; border-radius: 10px; }

.cal-menu {
  position: absolute; top: 100%; inset-inline-start: 0; z-index: 6;
  background: #fff; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(30, 43, 60, 0.15);
  min-width: 220px; padding: 0.3rem; display: flex; flex-direction: column;
  opacity: 0; transform: translateY(-4px); transition: opacity 120ms, transform 120ms;
}
.cal-menu.open { opacity: 1; transform: none; }
.cal-menu a, .cal-menu button {
  text-align: start; background: none; border: none; cursor: pointer;
  padding: 0.5rem 0.7rem; border-radius: 8px; font-size: 0.85rem; color: var(--ink); text-decoration: none;
}
.cal-menu a:hover, .cal-menu button:hover { background: var(--accent-soft); color: var(--accent); }
.todo-item .remove {
  background: none; border: none; cursor: pointer;
  color: var(--ink-soft); font-size: 1.1rem; line-height: 1; padding: 0 0.25rem;
  opacity: 0; transition: opacity 120ms;
}
.todo-item:hover .remove, .todo-item:focus-within .remove { opacity: 1; }
.todo-item .remove:hover { color: var(--danger); }

.done-list .todo-item { color: var(--ink-soft); }
.done-list .title { text-decoration: line-through; text-decoration-color: var(--gold); text-decoration-thickness: 2px; }
.done-list input[type="checkbox"] { accent-color: var(--gold); }
.done-list .when { font-size: 0.72rem; color: var(--ink-soft); white-space: nowrap; }

.achievements-heading {
  margin-top: 1.25rem;
  padding-top: 0.9rem;
  border-top: 2px solid var(--gold);
  color: var(--gold);
  display: flex; align-items: center; gap: 0.5rem;
}
.count {
  background: var(--gold); color: #fff;
  font-size: 0.75rem; font-weight: 600;
  border-radius: 999px; padding: 0.05rem 0.5rem;
}

.empty { color: var(--ink-soft); font-size: 0.85rem; margin: 0.5rem 0; }
.empty[hidden] { display: none; }

/* completion animation */
@keyframes settle { from { transform: translateX(-6px); opacity: 0; } to { transform: none; opacity: 1; } }
.todo-item.just-moved { animation: settle 220ms ease-out; }

/* ───────────── Centre panel: mode switch ───────────── */
.panel-map { padding: 0; position: relative; }
.mode-switch {
  display: flex; gap: 0.25rem;
  padding: 0.6rem 0.85rem 0;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
.mode-tab {
  background: none; border: none; cursor: pointer;
  padding: 0.5rem 0.9rem 0.6rem;
  color: var(--ink-soft); font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.mode-tab:hover { color: var(--ink); }
.mode-tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
.mode-spacer { flex: 1; }
.mode-action { align-self: center; margin-bottom: 0.35rem; white-space: nowrap; }

/* Fullscreen workspace: the board itself goes fullscreen so the side panels and
   their edge tabs stay inside it and remain usable. */
.board:fullscreen {
  background: var(--ground);
  padding: 0.75rem var(--board-pad) 0.75rem;
  height: 100%;
}
.board:fullscreen .panel-map { border-radius: var(--radius); }
.mode-pane { display: none; flex: 1; min-height: 0; position: relative; flex-direction: column; }
.mode-pane.active { display: flex; }

/* ───────────── Mind map ───────────── */

.map-toolbar {
  position: absolute; top: 0.85rem; inset-inline-start: 0.85rem; z-index: 2;
  display: flex; gap: 0.4rem; align-items: center;
  background: rgba(248, 250, 249, 0.9);
  backdrop-filter: blur(4px);
  padding: 0.35rem; border-radius: 12px;
}
.map-status { font-size: 0.8rem; color: var(--ink-soft); padding: 0 0.4rem; }
.toolbar-sep { width: 1px; height: 22px; background: var(--line); margin: 0 0.2rem; }
.shape-group { display: flex; gap: 0.25rem; }
.btn-ghost.shape.active { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.dialog-title { margin: 0; font-size: 1.05rem; }

.map {
  width: 100%; height: 100%;
  background:
    radial-gradient(circle at 1px 1px, #e3e9f1 1px, transparent 1.5px) 0 0 / 22px 22px,
    #ffffff;
  cursor: grab;
  touch-action: none;
}
.map.panning { cursor: grabbing; }

.link {
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
  opacity: 0.8;
}

.node { cursor: pointer; }
.node path {
  filter: url(#shadow);
  stroke-width: 2.5;
  transition: stroke-width 100ms;
}
/* Font, size and fill are set as SVG presentation attributes in renderMap so the
   user's chosen style wins — a CSS rule here would override those attributes and
   made cloud labels white-on-white. */
.node text {
  pointer-events: none;
  user-select: none;
}
.node.root path { stroke-width: 0; }
.node text { direction: ltr; unicode-bidi: plaintext; }
html[dir="rtl"] .node text { direction: rtl; }
.node.selected path { stroke: #1e2b3c; stroke-width: 3.5; stroke-dasharray: 6 4; }
.node.dragging path { filter: none; }

/* "+" handle: always visible on the centre so the first branch is obvious,
   and on hover or selection for every other node. */
.node-add {
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.14s ease;
}
.node-add text { pointer-events: none; user-select: none; }
.node-add circle { filter: none; stroke: #fff; stroke-width: 2; }
.node:hover .node-add,
.node.selected .node-add,
.node.root .node-add { opacity: 1; }
.node-add:hover circle { stroke: var(--accent); }
.node.dragging .node-add { opacity: 0; }

/* ───────────── Map style popover ───────────── */
.style-pop {
  position: absolute; top: 3.2rem; inset-inline-start: 0.9rem; z-index: 6;
  width: 250px; padding: 0.8rem 0.9rem;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: 14px; box-shadow: 0 10px 30px rgba(30, 43, 60, 0.18);
  display: flex; flex-direction: column; gap: 0.5rem;
}
.style-pop[hidden] { display: none; }
.style-label { margin: 0; font-size: 0.75rem; color: var(--ink-soft); font-weight: 600; }
.style-swatches { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.style-dot {
  width: 24px; height: 24px; border-radius: 50%;
  border: 2px solid transparent; cursor: pointer; padding: 0;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}
.style-dot.on { border-color: var(--ink); }
/* Palette + ink swatches (PALETTE and INKS in app.js). */
.style-dot[data-c="1f7a8c"] { background: #1f7a8c; }
.style-dot[data-c="c9962b"] { background: #c9962b; }
.style-dot[data-c="7b4fa3"] { background: #7b4fa3; }
.style-dot[data-c="2e8b57"] { background: #2e8b57; }
.style-dot[data-c="c4553a"] { background: #c4553a; }
.style-dot[data-c="3a6fb0"] { background: #3a6fb0; }
.style-dot[data-c="b8377a"] { background: #b8377a; }
.style-dot[data-c="5e8f2e"] { background: #5e8f2e; }
.style-dot[data-c="1e2b3c"] { background: #1e2b3c; }
.style-dot[data-c="ffffff"] { background: #ffffff; }
.style-dot.auto {
  background: var(--paper); font-size: 0.6rem; color: var(--ink-soft);
  border: 1px dashed var(--line); width: auto; border-radius: 999px; padding: 0 0.5rem;
}
.style-dot.auto.on { border: 1px solid var(--accent); color: var(--accent); }
.style-row {
  display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
  font-size: 0.8rem; color: var(--ink-soft);
}
.style-row select, .style-row input[type="range"] { max-width: 140px; }
.style-row input[type="color"] {
  width: 46px; height: 30px; padding: 2px;
  background: var(--paper);
  border: 1px solid var(--line); border-radius: 8px;
  cursor: pointer;
}
.style-row .chip.small { padding: 0.15rem 0.6rem; font-size: 0.72rem; }
.style-row .chip.active { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.style-row select {
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--line); border-radius: 8px; padding: 0.2rem 0.3rem;
}
.style-actions { display: flex; justify-content: space-between; gap: 0.5rem; }

/* ───────────── "Before you leave" dialog ───────────── */
.leave-options { display: flex; flex-direction: column; gap: 0.5rem; margin: 0.25rem 0 0.5rem; }
.leave-options button { width: 100%; text-align: start; padding: 0.6rem 0.9rem; }

/* ───────────── Password reset page ───────────── */
.reset-page { display: block; background: var(--ground); }
.reset-wrap {
  max-width: 420px; margin: 8vh auto; padding: 1.75rem;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: 0 10px 34px rgba(30, 43, 60, 0.08);
}
.reset-wrap h1 { font-size: 1.15rem; margin: 0 0 1rem; }
.reset-wrap label { display: block; margin-bottom: 0.9rem; font-size: 0.86rem; color: var(--ink-soft); }
.reset-wrap label input { margin-top: 0.3rem; }
.reset-hint { font-size: 0.78rem; color: var(--ink-soft); margin: 0 0 1rem; }
.reset-ok   { color: #2e8b57; font-weight: 600; }
.reset-bad  { color: var(--danger); font-size: 0.85rem; margin: 0 0 0.75rem; }
.reset-wrap .btn-primary { display: inline-block; text-decoration: none; }

/* ───────────── Calendar choice sheet ───────────── */
.cal-sheet { width: min(360px, 92vw); }
.cal-sheet .confirm-text { margin-bottom: 0.75rem; font-weight: 600; }
.cal-opt {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.1rem;
  width: 100%; margin-bottom: 0.45rem; padding: 0.7rem 0.8rem;
  background: var(--ground); color: var(--ink);
  border: 1px solid var(--line); border-radius: 12px;
  font: inherit; cursor: pointer; text-align: start;
  text-decoration: none;          /* they are anchors, not buttons */
  min-height: 52px; justify-content: center;
}
.cal-opt:hover { border-color: var(--accent); background: var(--accent-soft); }
.cal-opt strong { font-size: 0.92rem; font-weight: 600; }
.cal-opt small { font-size: 0.72rem; color: var(--ink-soft); }

/* ───────────── One-click calendar ───────────── */
.cal-all { flex: none; white-space: nowrap; }
.cal-all.ready {
  border-color: var(--accent); color: var(--accent);
  background: var(--accent-soft); font-weight: 600;
}
.due.cal-quick {
  background: #e9f6ee; color: #1d6b42; border: 1px solid #bfe3cd;
  font-weight: 600;
}
.due.cal-quick:hover { background: #d8f0e2; }
:root[data-theme="dark"] .due.cal-quick { background: #1d3a2a; color: #a9e6c3; border-color: #2c5a41; }

/* ───────────── Task notes ───────────── */
.due.has-note { border-color: var(--gold); color: #8a6412; background: #fdf4e0; }
.todo-note {
  margin: 0.3rem 0 0;
  font-size: 0.8rem; line-height: 1.45;
  color: var(--ink-soft);
  white-space: pre-wrap;
  border-inline-start: 2px solid var(--line);
  padding-inline-start: 0.5rem;
}
.note-editor {
  width: 100%; max-width: 100%; box-sizing: border-box;
  margin-top: 0.35rem;
  font: inherit; font-size: 0.82rem;
  color: var(--ink); background: var(--paper);
  border: 1px solid var(--accent); border-radius: 8px;
  padding: 0.4rem 0.5rem; resize: vertical;
}
/* Defence in depth: should anything else land in the row, it wraps instead of
   squeezing the title into a vertical column. */
.todo-item { flex-wrap: wrap; }
.todo-main { flex: 1 1 60%; }
:root[data-theme="dark"] .due.has-note { background: #3a2f14; color: #f2dfae; }

/* Active mind map in the خرائطي drawer. */
.library-item.active .library-open { color: var(--accent); font-weight: 600; }

/* ───────────── Secretary quick actions (chat panel) ───────────── */
.chat-actions {
  display: flex; flex-wrap: wrap; gap: 0.35rem;
  margin: 0.35rem 0 0.5rem;
}
.chat-actions .chip { font-size: 0.78rem; }

/* ───────────── Guest "save your work" reminder ───────────── */
.guest-save {
  display: flex; align-items: center; gap: 0.7rem;
  margin: 0.75rem 1.5rem 0;
  padding: 0.7rem 1rem;
  background: #fff6e2;
  border: 1px solid var(--gold);
  border-radius: 12px;
  color: #6b4d12;
  font-size: 0.86rem;
}
.guest-save[hidden] { display: none; }
.guest-save p { margin: 0; flex: 1; }
.guest-save-icon { font-size: 1.1rem; }
:root[data-theme="dark"] .guest-save { background: #3a2f14; color: #f2dfae; }

/* ───────────── In-page confirm (works inside fullscreen) ───────────── */
.confirm-back {
  position: absolute; inset: 0; z-index: 50;
  display: grid; place-items: center;
  background: rgba(15, 25, 38, 0.45);
}
.confirm-box {
  direction: ltr;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--line); border-radius: 14px;
  padding: 1.1rem 1.25rem; min-width: 280px; max-width: 90vw;
  box-shadow: 0 18px 50px rgba(15, 25, 38, 0.35);
}
html[dir="rtl"] .confirm-box { direction: rtl; }
.confirm-text { margin: 0 0 1rem; font-size: 0.95rem; }
.confirm-actions { display: flex; gap: 0.5rem; justify-content: flex-start; }

/* ───────────── Auth field feedback ───────────── */
.field-hint, .field-note {
  margin: -0.35rem 0 0;
  font-size: 0.76rem;
  color: var(--ink-soft);
}
.field-hint.ok  { color: #2e8b57; }
.field-hint.bad { color: var(--danger); }
.field-hint[hidden], .field-note[hidden] { display: none; }

.node-editor {
  position: absolute;
  z-index: 3;
  width: auto;
  min-width: 140px;
  border-radius: 999px;
  font-size: 13px;
  padding: 0.35rem 0.8rem;
  box-shadow: 0 4px 16px rgba(15, 42, 51, 0.2);
}

/* ───────────── Sketch board ───────────── */
.board-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.9rem;
  padding: 0.55rem 0.85rem;
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
.tool-group { display: flex; align-items: center; gap: 0.3rem; }
.tool-group.grow { flex: 1; justify-content: flex-end; min-width: 260px; }
.tool-group.grow input { max-width: 180px; padding: 0.3rem 0.6rem; font-size: 0.85rem; }
.tool {
  width: 32px; height: 32px; border-radius: 9px;
  border: 1px solid var(--line); background: #fff; cursor: pointer;
  font-size: 1rem; line-height: 1; color: var(--ink-soft);
}
.tool:hover { border-color: var(--accent); color: var(--accent); }
.tool.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.swatch {
  width: 22px; height: 22px; border-radius: 50%; cursor: pointer;
  border: 2px solid #fff; box-shadow: 0 0 0 1px var(--line);
}
.swatch.active { box-shadow: 0 0 0 2px var(--ink); }
.width-label { display: flex; align-items: center; gap: 0.4rem; font-size: 0.8rem; color: var(--ink-soft); }
.width-label input { width: 90px; accent-color: var(--accent); }

.board-stage {
  position: relative; flex: 1; min-height: 0; overflow: hidden;
  /* Without this a finger drag scrolls the page instead of drawing, so the
     board appears to slide away under the stroke. */
  touch-action: none;
  overscroll-behavior: contain;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.board-stage canvas { position: absolute; inset: 0; touch-action: none; }
.board-stage[data-board="white"] {
  background: #ffffff;    /* a plain sheet — no grid */
}
.board-stage[data-board="chalk"] {
  background:
    radial-gradient(ellipse at 20% 30%, rgba(255,255,255,0.06), transparent 55%),
    radial-gradient(ellipse at 80% 70%, rgba(255,255,255,0.05), transparent 50%),
    repeating-linear-gradient(115deg, rgba(255,255,255,0.015) 0 2px, transparent 2px 6px),
    #2f4f45;
  box-shadow: inset 0 0 0 10px #6b4a2b, inset 0 0 0 12px #4e341d;
}
.board-stage[data-board="chalk"] + .sketch-library { color: var(--ink); }
.board-text {
  position: absolute; z-index: 2;
  background: rgba(255,255,255,0.85); border: 1px dashed var(--accent);
  border-radius: 6px; padding: 0.15rem 0.4rem; font-weight: 500; width: auto; min-width: 120px;
}

.sketch-library {
  position: absolute; top: 0; bottom: 0; inset-inline-end: 0;
  width: 300px; max-width: 90%;
  background: var(--paper); border-inline-start: 1px solid var(--line);
  box-shadow: -8px 0 24px rgba(15,42,51,0.12);
  padding: 0.9rem; overflow-y: auto; z-index: 4;
}
.sketch-library[hidden] { display: none; }
.library-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.6rem; }
.library-head h3 { margin: 0; font-size: 1rem; }
.library-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.library-item { display: flex; align-items: stretch; gap: 0.3rem; }
.library-open {
  flex: 1; display: flex; align-items: center; gap: 0.6rem;
  background: #fff; border: 1px solid var(--line); border-radius: 10px;
  padding: 0.45rem; cursor: pointer; text-align: start;
}
.library-open:hover { border-color: var(--accent); }
.library-item.current .library-open { border-color: var(--accent); background: var(--accent-soft); }
.library-item.new .library-open { justify-content: center; color: var(--accent); font-weight: 600; border-style: dashed; }
.library-open img { width: 72px; height: 45px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); }
.library-meta { display: flex; flex-direction: column; font-size: 0.85rem; font-weight: 500; }
.library-meta small { color: var(--ink-soft); font-weight: 400; font-size: 0.72rem; }
.library-delete { background: none; border: none; color: var(--ink-soft); cursor: pointer; font-size: 1.1rem; padding: 0 0.3rem; }
.library-delete:hover { color: var(--danger); }

/* ───────────── Account dialog ───────────── */
.auth-dialog {
  border: none; border-radius: 18px; padding: 0;
  width: min(420px, 92vw);
  box-shadow: 0 24px 60px rgba(15,42,51,0.3);
  font-family: inherit; color: var(--ink);
}
.auth-dialog::backdrop { background: rgba(22,48,58,0.45); backdrop-filter: blur(2px); }
.auth-form { padding: 1.4rem; display: flex; flex-direction: column; gap: 0.8rem; }
.auth-tabs { display: flex; border-bottom: 1px solid var(--line); }
.auth-tab {
  flex: 1; background: none; border: none; cursor: pointer;
  padding: 0.5rem; color: var(--ink-soft); border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.auth-tab.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
.auth-note { margin: 0; font-size: 0.82rem; color: var(--ink-soft); }
.auth-form label { display: flex; flex-direction: column; gap: 0.3rem; font-size: 0.85rem; font-weight: 500; }
.auth-form label[hidden] { display: none; }
.auth-error { margin: 0; color: var(--danger); font-size: 0.82rem; background: #f8e5e4; padding: 0.45rem 0.7rem; border-radius: 8px; }
.auth-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 0.3rem; }

/* ───────────── Toast ───────────── */
.toast {
  position: fixed; bottom: 3.2rem; inset-inline-start: 50%; transform: translate(50%, 20px);
  background: var(--ink); color: #fff; padding: 0.6rem 1rem; border-radius: 12px;
  font-size: 0.85rem; opacity: 0; pointer-events: none; transition: opacity 180ms, transform 180ms; z-index: 50;
}
.toast.show { opacity: 1; transform: translate(50%, 0); }
.toast.success { background: #2e8b57; }
.toast.error { background: var(--danger); }

/* ───────────── Chat panel ───────────── */
.chat-head { display: flex; align-items: center; gap: 0.6rem; }
.chat-head h2 { flex: 1; }

.chat-log {
  flex: 1;
  /* Without min-height:0 a flex item refuses to shrink below its content, so
     the log stops scrolling and the controls below it squeeze it out of view. */
  min-height: 0;
  overflow-y: auto;
  margin: 0.9rem 0 0.6rem;
  display: flex; flex-direction: column; gap: 0.6rem;
  scroll-behavior: smooth;
}
.msg {
  max-width: 88%;
  padding: 0.55rem 0.8rem;
  border-radius: 14px;
  font-size: 0.9rem;
  white-space: pre-wrap;
  word-break: break-word;
}
.msg.user { align-self: flex-end; background: var(--accent); color: #fff; border-bottom-right-radius: 4px; }
.msg.assistant { align-self: flex-start; background: var(--ground); border-bottom-left-radius: 4px; }
.msg.error { align-self: stretch; background: #f8e5e4; color: var(--danger); font-size: 0.82rem; }
.msg.pending { color: var(--ink-soft); font-style: italic; }

.context-toggle { display: flex; align-items: center; gap: 0.45rem; font-size: 0.8rem; color: var(--ink-soft); margin-bottom: 0.5rem; }
.context-toggle input { accent-color: var(--accent); }

.chat-form { display: flex; gap: 0.5rem; align-items: flex-end; }
.chat-form textarea { resize: none; }

/* ───────────── Responsive ───────────── */
@media (max-width: 1100px) {
  .board { grid-template-columns: 260px 1fr; grid-template-rows: 1fr auto; }
  .panel-chat { grid-column: 1 / -1; max-height: 40vh; }
  /* The layout stacks here, so the edge handles have no border to sit on.
     Hide them and force the panels back on, or they could not be reopened. */
  .edge-tab { display: none; }
  .board:not(:fullscreen).hide-todo > .panel-todo,
  .board:not(:fullscreen).hide-chat > .panel-chat {
    padding: 1.1rem; border-width: 1px; opacity: 1; pointer-events: auto;
  }
  /* Rotated fullscreen on a phone: the workspace gets the whole screen, and
     the toolbar's own buttons are how you come back. */
  .board:fullscreen {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
    padding: 0.4rem;
    gap: 0.4rem;
  }
  .board:fullscreen.hide-todo > .panel-todo,
  .board:fullscreen.hide-chat > .panel-chat { display: none; }
}
/* ═════════════════ Mobile: one panel at a time, bottom nav ═════════════════
   Stacking three panels down a phone screen left every one of them too short
   to work in. Below 900px the board shows a single full-height panel and the
   bottom bar switches between them. */
.mobile-nav { display: none; }

@media (max-width: 900px) {
  :root { --mobile-nav-h: 60px; }

  /* Mobile browsers shrink the visible area when their address bar is showing.
     100% resolves against the larger initial viewport, which pushes the
     composer under the browser chrome; 100dvh tracks the real one. */
  html, body { height: 100dvh; }

  .board {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
    gap: 0;
    padding: 0.6rem 0.6rem calc(0.6rem + var(--mobile-nav-h));
  }
  /* The bottom bar decides what is on screen, not the desktop hide classes. */
  .board > .panel { display: none; }
  .board[data-view="todo"] > .panel-todo,
  .board[data-view="map"]  > .panel-map,
  .board[data-view="chat"] > .panel-chat {
    display: flex;
    opacity: 1;
    pointer-events: auto;
    border-width: 1px;
    /* The 1100px tablet rules cap the chat at 40vh and span it across columns.
       Both must be undone here or the panel is stuck at 40% of the screen and
       its contents get crushed. */
    max-height: none;
    grid-column: auto;
    grid-row: auto;
  }
  .board[data-view="todo"] > .panel-todo,
  .board[data-view="chat"] > .panel-chat { padding: 1rem; }
  .board[data-view="map"] > .panel-map { padding: 0; }

  .mobile-nav {
    position: fixed; inset-inline: 0; bottom: 0; z-index: 30;
    display: flex;
    height: var(--mobile-nav-h);
    padding-bottom: env(safe-area-inset-bottom, 0);
    background: var(--paper);
    border-top: 1px solid var(--line);
    box-shadow: 0 -4px 18px rgba(30, 43, 60, 0.08);
  }
  .mnav {
    flex: 1;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.15rem;
    background: none; border: none; cursor: pointer;
    color: var(--ink-soft); font: inherit; font-size: 0.7rem;
    padding: 0; min-height: 48px;          /* comfortable touch target */
  }
  .mnav-icon { width: 1.45rem; height: 1.45rem; stroke-width: 1.6; }
  .mnav.active { color: var(--accent); font-weight: 600; }
  .mnav.active .mnav-icon { stroke-width: 2.1; }

  /* Icon above a small caption, with no button chrome — the pattern every
     phone app uses. Icon-only was compact but unreadable: seven identical
     boxes tell the user nothing about what they do. */
  .map-toolbar, .mode-switch { flex-wrap: nowrap; overflow: visible; gap: 0; }
  /* Anchored as a real bar. As a floating overlay it never spanned the width,
     so every caption was squeezed into an ellipsis. */
  .map-toolbar {
    position: static;
    padding: 0.3rem 0.2rem;
    justify-content: space-around;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    border-radius: 0;
    backdrop-filter: none;
  }
  .map-toolbar .btn-ghost,
  .mode-tab, .mode-action {
    flex: 1 1 0;
    min-width: 0; min-height: 48px;
    flex-direction: column; gap: 0.15rem;
    padding: 0.3rem 0.1rem;
    background: none; border: none; box-shadow: none;
    color: var(--ink-soft);
    font-size: 0.6rem; font-weight: 500; line-height: 1.1;
  }
  .map-toolbar .btn-ghost .ic, .mode-tab .ic, .mode-action .ic {
    width: 1.35rem; height: 1.35rem; stroke-width: 1.6;
  }
  /* Short captions on a phone. The full wording ("الخريطة الذهنية",
     "ملء الشاشة") only ever rendered as an ellipsis at this width, which is
     worse than no label at all. */
  .btn-label { display: none; }
  .btn-short { display: block; white-space: nowrap; }
  /* Pressed and selected states carry the meaning that borders used to. */
  .map-toolbar .btn-ghost:active,
  .mode-action:active { color: var(--accent); }
  .map-toolbar .btn-ghost:disabled { opacity: 0.35; }
  .mode-tab { border-bottom: 2px solid transparent; }
  .mode-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
  .mode-tab.active .ic { stroke-width: 2.1; }

  .toolbar-sep { display: none; }
  .map-status { display: none; }
  /* Shapes only apply to a selected branch, so they stay out of the way until
     one is selected rather than sitting there greyed out. */
  .shape-group { display: contents; }
  .map-toolbar .shape { display: none; }
  .map-toolbar.has-selection .shape { display: inline-flex; }

  /* The board toolbar has genuinely many tools, so it still scrolls — but it
     is a single row of icons, which reads as scrollable. */
  .board-toolbar { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; gap: 0.25rem; }
  .board-toolbar::-webkit-scrollbar { display: none; }
  .board-toolbar > * { flex: none; }
  .tool-group.grow { flex: none; }
  .tool-group.grow #sketch-title { width: 110px; }

  /* Bigger hit areas throughout. */
  .btn-primary, .btn-ghost, .chip, .tool { min-height: 38px; }
  .todo-item .remove, .due.ghost { opacity: 1; }

  /* The chat panel carries a lot of controls under the log — a heading, two
     checkboxes, three action chips and the composer. On a phone those eat the
     whole column and the conversation disappears. Give the log a floor and
     make everything under it as compact as it can be. */
  /* The welcome banner costs ~80px — more than a fifth of a phone screen — and
     the bottom bar already makes the app self-explanatory. The guest-save
     warning still shows, because that one matters. */
  #welcome { display: none; }

  /* The unsaved-work warning was costing up to 139px — a quarter of a small
     phone — and squeezing the conversation to a single line. Keep the warning,
     drop the explanation, and put it all on one row. */
  .guest-save {
    margin: 0.4rem 0.5rem 0;
    padding: 0.45rem 0.6rem;
    gap: 0.5rem;
    font-size: 0.75rem;
    align-items: center;
  }
  .guest-save .gs-long { display: none; }
  .guest-save-icon { font-size: 0.95rem; }
  .guest-save .btn-primary { min-height: 30px; padding: 0.2rem 0.7rem; font-size: 0.75rem; white-space: nowrap; }
  .guest-save .btn-ghost { min-height: 26px; padding: 0 0.35rem; }

  .board[data-view="chat"] > .panel-chat { padding: 0.6rem 0.75rem; }
  .chat-log {
    /* No floor here: flex:1 already gives it every spare pixel, and a fixed
       minimum would starve the action chips and composer below it. */
    margin: 0.4rem 0 0.35rem;
  }
  .msg { max-width: 92%; font-size: 0.88rem; padding: 0.45rem 0.7rem; }
  .context-toggle {
    font-size: 0.68rem; margin-bottom: 0.1rem; line-height: 1.25;
    align-items: flex-start; gap: 0.35rem;
  }
  .context-toggle input { margin-top: 0.1rem; flex: none; width: 15px; height: 15px; }
  /* 16px keeps iOS from zooming the whole page when the field takes focus,
     which used to leave the map scrolled somewhere else after renaming. */
  .node-editor { font-size: 16px; min-width: 160px; padding: 0.45rem 0.8rem; }

  .chat-head { align-items: center; }
  .chat-head h2 { font-size: 0.9rem; }
  .chat-head .btn-ghost { min-height: 30px; padding: 0.2rem 0.6rem; font-size: 0.75rem; }
  .chat-actions {
    flex-wrap: nowrap; overflow-x: auto; gap: 0.3rem;
    margin: 0.25rem 0 0.4rem; padding-bottom: 0.15rem;
    scrollbar-width: none;
  }
  .chat-actions::-webkit-scrollbar { display: none; }
  .chat-actions .chip { flex: none; min-height: 32px; white-space: nowrap; font-size: 0.74rem; }
  .chat-form { gap: 0.4rem; }
  /* rows="3" would otherwise fix this at ~91px; two lines is plenty on a phone
     and the field still grows when focused. */
  .chat-form textarea { height: 58px; min-height: 58px; max-height: 110px; }
  .chat-form textarea:focus { height: 92px; }
  .chat-form .btn-primary { padding: 0.4rem 0.9rem; align-self: stretch; }

  .topbar { padding: 0.6rem 0.9rem; gap: 0.6rem; }
  .topbar-hint { display: none; }
  .welcome, .guest-save { margin: 0.6rem 0.6rem 0; }
  .footer { display: none; }
  .edge-tab { display: none; }

  /* Dialogs and popovers use the width they have. */
  .auth-dialog { width: calc(100vw - 1.5rem); max-width: none; }
  .style-pop { inset-inline: 0.6rem; width: auto; }

  /* Rotated fullscreen: the panel takes the whole screen, nav out of the way. */
  .board:fullscreen { padding: 0.4rem; }
  .board:fullscreen ~ .mobile-nav { display: none; }
}

@media (max-width: 720px) {
  .board { padding: 0.5rem 0.5rem calc(0.5rem + var(--mobile-nav-h)); }
  .add-row { flex-wrap: wrap; }
  .chat-form textarea { font-size: 16px; }   /* stops iOS zooming on focus */
  #todo-input { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
