/* ═══════════════════════════════════════════════════════════════════
   PARSLEY'S MAGIC BRUSH — style.css
   ═══════════════════════════════════════════════════════════════════ */


/* ─────────────────────────────────────────────────────────────────
   ANIMATION TIMINGS — must stay in sync with src/constants.js
   ─────────────────────────────────────────────────────────────────
   ANIM_HWR_FADE           = 200ms  → .mb-hwr-label, .mb-hwr-indicator opacity transition
   ANIM_HWR_FADE_CLEANUP   = 210ms  → setTimeout in hwr/recognizer.js, hwr/convert.js
   ANIM_HWR_PARTICLE_PHASE = 800ms  → particle burst rAF loop in hwr/ink.js
   ANIM_HWR_PARTICLE_CLEANUP = 500ms → setTimeout to remove particle DOM nodes
   ANIM_WATERMARK_EXPIRY   = 8000ms → watermark retirement in boot.js
   ───────────────────────────────────────────────────────────────── */

/* ─────────────────────────────────────────────────────────────────
   0. LOCAL FONTS
   ───────────────────────────────────────────────────────────────── */

@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  src: url('../assets/fonts/AtkinsonHyperlegibleNext-VariableFont_wght.ttf') format('truetype');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  src: url('../assets/fonts/AtkinsonHyperlegibleNext-Italic-VariableFont_wght.ttf') format('truetype');
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Lora';
  src: url('../assets/fonts/Lora-VariableFont_wght.ttf') format('truetype');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Lora';
  src: url('../assets/fonts/Lora-Italic-VariableFont_wght.ttf') format('truetype');
  font-weight: 400 700;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'Kalam';
  src: url('../assets/fonts/Kalam-Regular.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Kalam';
  src: url('../assets/fonts/Kalam-Bold.ttf') format('truetype');
  font-weight: bold;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Libre Bodoni';
  src: url('../assets/fonts/LibreBodoni-VariableFont_wght.ttf') format('truetype');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Libre Bodoni';
  src: url('../assets/fonts/LibreBodoni-Italic-VariableFont_wght.ttf') format('truetype');
  font-weight: 400 700;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'ABeeZee';
  src: url('../assets/fonts/ABeeZee-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'ABeeZee';
  src: url('../assets/fonts/ABeeZee-Italic.ttf') format('truetype');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'JetBrains Mono';
  src: url('../assets/fonts/JetBrainsMono[wght].ttf') format('truetype');
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('../assets/fonts/JetBrainsMono-Italic[wght].ttf') format('truetype');
  font-weight: 100 800;
  font-style: italic;
  font-display: swap;
}

/* ─────────────────────────────────────────────────────────────────
   1. ROOT VARIABLES — Parsley design tokens + layout constants
   ───────────────────────────────────────────────────────────────── */
:root {
  /* ── Neutrals ── */
  --bg:           #F5F0E8;
  --bg-t:         #F5F0E8C0;
  --canvas-bg:    #FAF7F2;
  --card-bg:      #FDFCF9;
  --card-bg-t:    #FDFCF9E0;
  --text-1:       #3D2C2E;
  --text-1-t:     #3D2C2EE0;
  --text-2:       #6B5558;
  --text-3:       #A89080;
  --color-mist:   #C8C0B6;
  --color-border: #DDD6CC;

  /* ── Action — teal ── */
  --color-action:          #4E7C7E;
  --color-action-lt:       #EBF2F2;
  --color-action-bd:       #9EC4C5;
  --color-action-dk:       #3B696B;
  --color-action-lt-hover: #D9ECEC;

  /* ── Success — green ── */
  --color-success:          #5A7D5A;
  --color-success-lt:       #EBF2EB;
  --color-success-bd:       #9EC49E;
  --color-success-dk:       #476A48;
  --color-success-lt-hover: #DDE8DD;

  /* ── Warning — burnt orange ── */
  --color-warning:          #A25F40;
  --color-warning-lt:       #F5EAE4;
  --color-warning-bd:       #D9A88E;
  --color-warning-dk:       #8D4C2D;
  --color-warning-lt-hover: #EBD2C8;

  /* ── Danger — red ── */
  --color-danger:    #DC503C;
  --color-danger-lt: rgba(220, 80, 60, 0.15);

  /* ── Accent — periwinkle ── */
  --color-accent:          #5B7FAF;
  --color-accent-lt:       #EBF0F7;
  --color-accent-bd:       #B5C8E0;
  --color-accent-dk:       #4A6E9A;
  --color-accent-lt-hover: #D9E5F0;

  /* ── Typography ── */
  --font-title:   'Libre Bodoni', georgia, serif;
  --font-heading: 'Lora', georgia, serif;
  --font-sans:    'Atkinson Hyperlegible Next', 'Atkinson Hyperlegible', system-ui, sans-serif;
  --font-mono:    'JetBrains Mono', monospace;

  /* ── Type scale ── */
  --f-xs: 0.625rem;  /* 10px */
  --f-s:  0.75rem;   /* 12px */
  --f-m:  1rem;      /* 16px */
  --f-ml: 1.125rem;  /* 18px */
  --f-l:  1.5rem;    /* 24px */
  --f-xl: 2.5rem;    /* 40px */

  --lh-base: 1.5;

  /* ── Spacing ── */
  --xs: 0.25rem;  /*  4px */
  --s:  0.5rem;   /*  8px */
  --ms: 0.75rem;  /* 12px */
  --m:  1rem;     /* 16px */
  --l:  1.5rem;   /* 24px */
  --xl: 2rem;     /* 32px */
  --xxl: 2.5rem;   /* 40px */
  --3xl: 3rem;
  --tabs-h: 48;  /* px — matches --3xl; read by panel positioning JS */
  --4xl: 4rem;

  /* ── Shadows — warm, derived from --text-1 ── */
  --shadow-sm:  0 var(--border) var(--xs) rgba(61,44,46,0.10);
  --shadow:     0 var(--s) var(--s) rgba(61,44,46,0.08);
  --shadow-lg:  0 var(--s) var(--l) rgba(61,44,46,0.14);
  --shadow-xl:  0 var(--l) var(--xxl) rgba(61,44,46,0.18);
  --color-panel-border: var(--black-a18);

  /* ── Alpha fills — text-1 transparent layers for interactive states ── */
  --alpha-hover:  rgba(61,44,46,0.06);  /* standard hover background */
  --alpha-mid:    rgba(61,44,46,0.10);  /* mid-level selected state (between hover and active) */
  --alpha-active: rgba(61,44,46,0.14);  /* active/selected background */

  /* ── White ── */
  --white: #ffffff;

  /* ── White alpha tokens — for on-dark surfaces ── */
  --white-a10: rgba(255,255,255,0.10);
  --white-a25: rgba(255,255,255,0.25);
  --white-a50: rgba(255,255,255,0.50);
  --white-a75: rgba(255,255,255,0.75);
  --white-a85: rgba(255,255,255,0.85);

  /* ── Black alpha tokens — for scattered dark overlays ── */
  --black-a10: rgba(0, 0, 0, 0.10);
  --black-a18: rgba(0, 0, 0, 0.18);
  --black-a25: rgba(0, 0, 0, 0.25);
  --black-a50: rgba(0, 0, 0, 0.50);

  /* ── Text-1 alpha tokens — for text/element overlays ── */
  --text-1-a18: rgba(61,44,46,0.18);
  --text-1-a45: rgba(61,44,46,0.45);

  /* Motion — canonical transition tokens */
  --t-snap: 60ms;   /* all standard UI hover/interaction transitions */
  --t-fast: 120ms;  /* slightly longer animations (e.g. dot size) */
  --t-slow: 240ms;

  /* ── Focus rings ── */
  --ring-action:      rgba(78,124,126,0.35);
  --ring-action-soft: rgba(78,124,126,0.15);
  --ring-success:     rgba(90,125,90,0.35);
  --ring-warning:     rgba(162,95,64,0.35);
  --ring-accent:      rgba(91,127,175,0.35);
  --ring-neutral:     rgba(61,44,46,0.15);

  /* ── Border widths ── */
  --border:      1px;
  --border-bold: 2px;

  /* ── Border radius ── */
  --radius:   var(--xs);
  --radius-l: calc(var(--radius) * 2);

  /* ── Z-index ladder ── */
  --z-canvas:        1;
  --z-gif-overlay:   5;
  --z-ui:            10;
  --z-toolbar:       90;
  --z-panel:         100;
  --z-crop-overlay:  50;
  --z-picker:        200;
  --z-modal:         300;
  --z-hwr-popup:     320;
  --z-toast:         400;
}

/* ─────────────────────────────────────────────────────────────────
   2. RESET AND FUNDAMENTALS
   ───────────────────────────────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

button {
  font-family: var(--font-sans);
  cursor: pointer;
  border: none;
  background: none;
  user-select: none;
  -webkit-user-select: none;
}

button:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--ring-action);
}

input, textarea, select {
  font-family: var(--font-sans);
}

/* ─────────────────────────────────────────────────────────────────
   3. BASE
   ───────────────────────────────────────────────────────────────── */
html, body {
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  font-family: var(--font-sans);
  color: var(--text-1);
  font-size: var(--m);
  line-height: var(--lh-base);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Prevent scroll & zoom bounce on iOS/IWB */
  touch-action: manipulation;
  overscroll-behavior: none;
  /* Suppress the grey flash on tap (iOS/Android). We have our own :active /
     .active states; the default overlay just blocks our visual feedback. */
  -webkit-tap-highlight-color: transparent;
}

button {
  display: flex;
  align-items: center;
  justify-content: center;
  border: var(--border) solid transparent;
  background: transparent;
  flex-shrink: 0;
  touch-action: manipulation;
  transition: background var(--t-snap) ease, color var(--t-snap) ease;
  width: var(--xl);
  height: var(--xl);
  border-radius: var(--radius);
}

/* ─────────────────────────────────────────────────────────────────
   4. APP SHELL — flex column, full viewport
   ───────────────────────────────────────────────────────────────── */
#boot-screen {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  background: #fff;
}
#boot-screen[hidden] { display: none; }

#boot-spinner {
  width: 28px;
  height: 28px;
  border: 3px solid #e0e0e0;
  border-top-color: #aaa;
  border-radius: 50%;
  animation: boot-spin 0.75s linear infinite, boot-fade 0.3s ease 1s both;
}

@keyframes boot-spin {
  to { transform: rotate(360deg); }
}

@keyframes boot-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

#boot-status {
  font-family: sans-serif;
  font-size: 14px;
  color: #999;
  animation: boot-fade 0.3s ease 2s both;
}

#app {
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  height: var(--app-h, 100vh);
  width: 100vw;
  position: relative;
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;  /* suppress iOS long-press callout on canvas/buttons */
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

/* Phone = scaled tablet. #app renders at PHONE_LOGICAL_W logical px
   (540 — scaled-up hit targets for thumbs) and is CSS-scaled to fit
   the physical viewport. All layout, panels, and fabric interactions
   operate in the logical coordinate system. Keep the CSS value in
   sync with PHONE_LOGICAL_W in app.js. */
body.mode-phone {
  overflow: hidden;
}
body.mode-phone #app {
  width: 540px;
  height: var(--app-h, 100vh);
  transform: scale(var(--phone-scale, 1));
  transform-origin: top left;
}

/* On iOS 15.4+ (svh supported), size non-phone #app to the small viewport height —
   the height when the browser toolbar is fully visible. This prevents the app from
   overflowing when the Safari toolbar is shown, without relying on JS to track
   visualViewport changes that the browser may not always fire reliably. */
@supports (height: 100svh) {
  body:not(.mode-phone) #app {
    height: 100svh;
  }
}

/* Toolbar is pinned to top on tablet/phone; undock/reposition is an
   IWB-only affordance. Hide the dock pin button since it has nothing
   to toggle in these modes. */
body.mode-tablet #btn-ftp-dock,
body.mode-phone  #btn-ftp-dock { display: none; }


/* ─────────────────────────────────────────────────────────────────
   5. CANVAS CONTAINER — flex:1, paper background + overlays
   ───────────────────────────────────────────────────────────────── */
#canvas-container {
  order: 1;
  flex: 1;
  overflow: hidden;
  position: relative;
  touch-action: none;           /* Fabric handles its own pointer events */
  background-color: var(--canvas-bg);   /* warm cream — slightly warmer than card-bg */
  z-index: var(--z-canvas);
}

/* Fabric injects a wrapper div + the canvas element — both must fill */
#canvas-container > .canvas-container,
#canvas-container > .canvas-container > canvas {
  display: block;
}

/* main-canvas — let Fabric set position/z-index via its own inline styles */
#main-canvas {
  display: block;
}

/* Re-enable text selection on the canvas itself so Fabric text editing works */
#canvas-container canvas {
  user-select: text;
  -webkit-user-select: text;
}

/* Animated GIF overlay — <img> elements positioned above canvas, animated by browser.
   Layer lives inside Fabric's wrapperEl so it shares the canvas stacking context.
   z-index 5 sits between lower-canvas (auto) and upper-canvas (99) — GIFs render
   above completed objects but below the active drawing surface. */
#gif-overlay-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: var(--z-gif-overlay);
  overflow: hidden;
}

#gif-overlay-layer img {
  position: absolute;
  pointer-events: none;
}

/* ── Parsley watermark — centered, faint, empty-canvas only ── */
#parsley-watermark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 512px;
  height: 512px;
  /* stylelint-disable declaration-block-no-duplicate-properties */
  image-rendering: pixelated;  /* Chrome/Safari */
  image-rendering: crisp-edges; /* standard */
  /* stylelint-enable declaration-block-no-duplicate-properties */
  opacity: 0;
  pointer-events: none;
  user-select: none;
  z-index: var(--z-canvas);
  transition: opacity 1800ms ease;
}
#parsley-watermark.visible { opacity: 0.5; }
#parsley-watermark.dark-bg { filter: invert(1); }

#text-drag-preview {
  position: absolute;
  border: var(--border-bold) dashed var(--color-action);
  border-radius: var(--radius);
  pointer-events: none;
  display: none;
  z-index: var(--z-ui);
}


/* ─────────────────────────────────────────────────────────────────
   6. BOARD TABS BAR — footer strip, distinct from toolbar
   Pill-style tabs, card-bg background, wordmark right-aligned.
   ───────────────────────────────────────────────────────────────── */

#board-tabs-bar {
  order: 2;   /* pinned to bottom by default */
  height: var(--3xl);
  background: var(--text-1);   /* warm dark brown — clearly distinct footer */
  border-top: none;
  display: flex;
  align-items: center;
  padding: 0 var(--s);
  gap: var(--m);
  overflow-x: auto;
  overflow-y: hidden;
  flex-shrink: 0;
  z-index: var(--z-ui);
  scrollbar-width: none;
}

#board-tabs-bar[data-position="top"] {
  order: 0;   /* pinned to top */
  border-bottom: var(--border) solid var(--color-border);
}

#board-tabs-bar::-webkit-scrollbar { display: none; }

/* Individual tab — sits inside the dark bar */
.board-tab {
  width: auto;
  height: var(--xxl);
  padding: 0 var(--m);
  background: transparent;
  border: none;
  border-radius: var(--radius-l);
  font-family: var(--font-sans);
  font-size: var(--f-s);
  font-weight: 400;
  color: var(--white-a75);
  display: inline-flex;
  align-items: center;
  gap: var(--s);
  white-space: nowrap;
  cursor: pointer;
  touch-action: manipulation;
  transition: background var(--t-snap) ease, color var(--t-snap) ease;
  flex-shrink: 0;
}

.board-tab:hover {
  background: var(--white-a10);
  color: var(--white-a75);
}

.board-tab:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--ring-action);
}

/* Active tab: white pill, dark text — inverted contrast for clear selection */
.board-tab.active {
  background: var(--white-a85);
  color: var(--text-1);
  font-weight: 500;
  padding-right: var(--s); /* less padding right — close btn adds its own space */
}

/* Tab label — truncates if long */
.tab-label {
  max-width: calc(var(--xxl) * 3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Close × — only shown on active tab */
.tab-close {
  width: var(--l);
  height: var(--l);
  min-width: var(--l);
  border-radius: var(--radius);
  border: none;
  background: transparent;
  color: var(--text-2);
  font-size: var(--f-s);
  line-height: 1;
  display: none;          /* hidden by default */
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
  transition: background var(--t-snap) ease, color var(--t-snap) ease;
  cursor: pointer;
}

/* Show close only on active tab */
.board-tab.active .tab-close {
  display: flex;
  color: var(--text-1-a45);
}

.tab-dup { opacity: 0.7; }
.tab-dup:hover { opacity: 1; background: var(--alpha-hover) !important; }

.board-tab.active .tab-close:hover {
  background: var(--alpha-mid);
  color: var(--text-1);
}

/* Add board button */
.tab-add {
  height: var(--xxl);
  width: var(--xxl);
  padding: 0;
  border-radius: var(--radius-l);
  border: none;
  background: transparent;
  color: var(--white-a50);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background var(--t-snap), color var(--t-snap);
}

.tab-add:hover {
  background: var(--white-a10);
  color: var(--white-a85);
}

/* Spacer — pushes wordmark right */
.tabs-spacer { flex: 1; }

/* App wordmark — lives in the tabs bar */

/* ── Board row action buttons ── */
.tab-action-btn {
  flex-direction: column;
  color: var(--white-a85);
}

.tab-action-btn svg {
  width: var(--f-ml);
  height: var(--f-ml);
}

.tab-action-btn .lbl {
  font-family: 'Lora', serif;
  font-style: italic;
  font-size: var(--f-xs);
  color: var(--white-a85);
  line-height: 1;
}

.tab-action-btn:hover {
  background: var(--white-a25);
  color: var(--white);
}

.tab-action-btn:disabled {
  opacity: 0.25;
  pointer-events: none;
}

.tab-action-btn.active {
  color: var(--white);
  background: var(--white-a10);
}

.tab-action-btn.danger { color: rgba(220, 80, 60, 0.7); }
.tab-action-btn.danger:hover { background: var(--color-danger-lt); color: var(--color-danger); }

#btn-tabs-pos { padding: 0 4px; min-width: 0; width: auto; }

/* Canonical divider style — var(--border) vertical line with standard colour token.
   Use .mb-divider--tab-bar for the special white-on-dark tabs bar variant. */
.mb-divider {
  width: 1px;
  height: var(--l);
  background: var(--color-border);
  margin: 0 var(--xs);
  flex-shrink: 0;
}
.mb-divider--tab-bar {
  height: var(--l);
  background: var(--white-a25);
}

/* Locked board row — hide everything except lock button */
#board-tabs-bar[data-locked="true"] .board-tab,
#board-tabs-bar[data-locked="true"] .tab-add,
#board-tabs-bar[data-locked="true"] .tabs-spacer,
#board-tabs-bar[data-locked="true"] .mb-divider {
  display: none;
}
#board-tabs-bar[data-locked="true"] .tab-action-btn:not(#btn-lock) {
  display: none;
}

/* Zoom slider widget */
.zoom-slider-wrap {
  display: flex;
  align-items: center;
  gap: var(--s);
  flex-shrink: 0;
}

#zoom-slider {
  -webkit-appearance: none;
  appearance: none;
  width: var(--4xl);
  height: var(--xs);
  border-radius: var(--radius);
  background: var(--white-a25);
  accent-color: var(--white-a85);
  cursor: pointer;
  outline: none;
}

#zoom-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: var(--f-s);
  height: var(--f-s);
  border-radius: 50%;
  background: var(--white-a85);
  cursor: pointer;
  transition: background var(--t-snap);
}

#zoom-slider:hover::-webkit-slider-thumb {
  background: var(--white);
}

#zoom-slider::-moz-range-thumb {
  width: var(--f-s);
  height: var(--f-s);
  border-radius: 50%;
  border: none;
  background: var(--white-a85);
  cursor: pointer;
}

.zoom-label {
  font-family: var(--font-sans);
  font-size: var(--f-s);
  color: var(--white-a75);
  width: 4ch;
  text-align: right;
  user-select: none;
  flex-shrink: 0;
}

#board-tabs-bar[data-locked="true"] .zoom-slider-wrap {
  display: none;
}

#board-tabs-bar[data-locked="true"] #btn-lock {
  margin-left: auto;
}

/* ── Help modal ── */
#help-modal {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(20, 15, 15, 0.55);
  z-index: var(--z-modal, 2000);
  align-items: center;
  justify-content: center;
  padding: var(--m);
}

#help-modal.open { display: flex; }

.help-card {
  background: var(--card-bg);
  border: var(--border) solid var(--color-panel-border);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-lg);
  width: min(640px, 100%);
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-size: var(--f-m);
}

.help-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--ms) var(--l) 0;
  flex-shrink: 0;
}

.help-header h2 {
  font-family: var(--font-title);
  font-size: var(--f-l);
  font-weight: 600;
  color: var(--color-action);
}

.help-close {
  width: var(--l);
  height: var(--l);
  border: none;
  border-radius: var(--radius);
  background: transparent;
  color: var(--text-3);
  font-size: var(--f-ml);
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.help-close:hover { background: var(--alpha-hover); color: var(--text-1); }

.help-body {
  padding: var(--l);
  overflow-y: auto;
  flex: 1;
}

.help-body h3 {
  font-size: var(--f-m);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-3);
  margin: var(--m) 0 var(--s);
}

.help-body h3:first-child { margin-top: 0; }

.help-intro {
  color: var(--text-2);
  margin: 0 0 var(--m);
  line-height: 1.5;
}

.help-note {
  color: var(--text-3);
  margin: var(--s) 0 0;
  font-style: italic;
}

.help-body p { color: var(--text-2); margin: var(--s) 0 0; }

.help-list {
  margin: 0;
  padding: 0 0 0 var(--m);
  color: var(--text-2);
  line-height: 1.6;
}
.help-list li { margin-bottom: var(--xs); }
.help-list li:last-child { margin-bottom: 0; }

.help-credit { margin-top: var(--l) !important; padding-top: var(--m); border-top: var(--border) solid var(--color-panel-border); }
.help-credit-link {
  color: var(--color-action);
  text-decoration: none;
  font-weight: 500;
  border-bottom: 1px solid color-mix(in srgb, var(--color-action) 40%, transparent);
  padding-bottom: 1px;
  transition: border-color 150ms, opacity 150ms;
}
.help-credit-link:hover { border-bottom-color: var(--color-action); opacity: 0.8; }

/* Inline rename input */
.tab-rename-input {
  width: 80px;
  font-size: var(--f-s);
  font-family: var(--font-sans);
  border: var(--border) solid var(--color-action-bd);
  border-radius: var(--radius);
  padding: var(--border) var(--xs);
  background: var(--card-bg);
  color: var(--text-1);
  outline: none;
}
.tab-rename-input:focus {
  box-shadow: 0 0 0 var(--border-bold) var(--ring-action-soft);
}

/* ── Board picker button (overflow mode) ── */
.board-picker-btn {
  display: flex;
  align-items: center;
  gap: var(--s);
  padding: 0 var(--ms) 0 var(--m);
}

.board-picker-btn .tab-label {
  max-width: 140px;
}

.picker-count {
  font-size: var(--f-s);
  opacity: 0.5;
  font-variant-numeric: tabular-nums;
}

/* ── Generic open-menu dropdown (print menu, etc.) ── */
.open-menu-dropdown {
  position: fixed;
  z-index: var(--z-panel);
  background: var(--card-bg);
  border: var(--border) solid var(--color-border);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-lg);
  padding: var(--xs);
  min-width: 140px;
}

.open-menu-item {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  gap: var(--s);
  width: 100%;
  padding: var(--s) var(--ms);
  border: none;
  background: transparent;
  border-radius: var(--radius);
  cursor: pointer;
  color: var(--text-1);
  font-size: var(--f-s);
  text-align: left;
}

.open-menu-item:hover {
  background: var(--alpha-hover);
}

.open-menu-item svg {
  color: var(--text-2);
  flex-shrink: 0;
}

/* ── Board picker dropdown ── */
#board-picker-dropdown {
  position: fixed;
  z-index: var(--z-panel);
  background: var(--card-bg);
  border: var(--border) solid var(--color-border);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-lg);
  padding: var(--xs);
  max-height: 320px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.ppi {
  display: flex;
  align-items: center;
  gap: var(--s);
  padding: var(--s) var(--ms);
  border-radius: var(--radius);
  cursor: pointer;
  user-select: none;
  min-height: var(--xxl);
}

.ppi:not(.active):hover {
  background: var(--alpha-hover);
}

.ppi.active {
  background: var(--color-action-lt);
  cursor: default;
}

.ppi-num {
  font-size: var(--f-s);
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  min-width: var(--f-ml);
  text-align: right;
  flex-shrink: 0;
}

.ppi-label {
  flex: 1;
  font-size: var(--f-s);
  color: var(--text-1);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ppi.active .ppi-label {
  color: var(--color-action);
  font-weight: 500;
}

.ppi-actions {
  display: flex;
  align-items: center;
  gap: var(--xs);
  margin-left: auto;
  flex-shrink: 0;
}

.ppi-btn {
  width: var(--l);
  height: var(--l);
  color: var(--text-2);
  padding: 0;
}

.ppi-btn:hover {
  background: var(--alpha-hover);
  color: var(--text-1);
}

.ppi-del:hover {
  background: var(--color-danger-lt);
  color: var(--color-danger);
}

.ppi-rename-input {
  flex: 1;
  font-size: var(--f-s);
  font-family: var(--font-sans);
  border: var(--border) solid var(--color-action-bd);
  border-radius: var(--radius);
  padding: var(--border) var(--xs);
  background: var(--card-bg);
  color: var(--text-1);
  outline: none;
  min-width: 0;
}

.ppi-rename-input:focus {
  box-shadow: 0 0 0 var(--border-bold) var(--ring-action-soft);
}

/* Lock button — full teal when active (locked state) */
#btn-lock.active {
  background: var(--color-action);
  color: var(--white);
}

/* ─────────────────────────────────────────────────────────────────
   8. SHARED TOOL WIDGETS — stroke-size popup, font-family popup,
      HWR popup, colour grid, theme picker.
      Used across draw / shape / text tool panels.
   ───────────────────────────────────────────────────────────────── */

.ssp-btn {
  width: var(--xxl);
  height: var(--xxl);
  transition: background var(--t-snap) ease, border-color var(--t-snap) ease;
}
.ssp-btn:hover  { background: var(--alpha-hover); }
.ssp-btn.active {
  background: var(--card-bg);
  box-shadow: var(--shadow-sm);
  border-color: transparent;
}

.ssp-dot {
  display: block;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--text-2);
  transition: background var(--t-snap) ease;
}
.ssp-btn.active .ssp-dot { background: var(--color-action); }

/* Stroke-size anchor — single button showing current size bar, pops over with presets */
.stroke-size-anchor {
  display: inline-flex;
  transition: background var(--t-snap) ease, border-color var(--t-snap) ease;
}
.stroke-size-anchor:hover { background: var(--alpha-hover); }
.stroke-size-anchor-dot {
  display: block;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--text-2);
  transition: width 120ms ease, height 120ms ease, background var(--t-snap) ease;
}

/* Stroke-size popup — the popover that opens from the anchor */
.stroke-size-popup {
  width: auto;
}
.stroke-size-popup .sss-popup-row {
  display: flex;
  align-items: center;
  gap: var(--xs);
  padding: var(--xs);
}
.widget-popup.text-align-popup {
  width: auto;
  padding: var(--xs);
}
.text-align-popup .tap-row {
  display: flex;
  align-items: center;
  gap: var(--xs);
}

/* Single-row panel shell — used by the refactored Draw / Shape / Text panels
   when they collapse onto one horizontal line. Also see the two-class selector
   `.ofb-tool-section.tool-controls-row` below, which overrides the default
   column layout when tool controls are docked inside the OFB. */
.tool-controls-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--xs);
  overflow: visible;
}

/* Emphasis variant for the Draw magic buttons (To text / To image). */
.mb-magic-btn {
  display: inline-flex;
  width: 6rem;
  gap: var(--xs);
  border-color: var(--color-action);
  color: var(--color-action);
  font-size: var(--f-s);
  font-weight: bold;
}
.mb-magic-btn:hover { background: var(--color-action-lt); }
.mb-magic-btn:disabled { opacity: 0.4; cursor: default; }
.mb-magic-btn .mb-magic-label {
  font-size: var(--f-s);
  letter-spacing: 0.02em;
}

/* Font-family anchor — a single button showing "Aa" in current font; pops over with full list */
.font-family-anchor {
  display: inline-flex;
  color: var(--text-2);
  font-size: var(--f-m);
  line-height: 1;
}
.font-family-anchor:hover { background: var(--alpha-hover); }

.font-family-popup {
  width: 160px !important;
  padding: var(--s) !important;
  gap: var(--xs) !important;
}

/* Font family popup divider — horizontal (height:1px) instead of vertical */
.mb-divider--horizontal {
  height: 1px;
  width: auto;
  margin: var(--xs) 0;
}

.ffp-font-btn {
  display: block;
  width: 100%;
  padding: var(--s) var(--ms);
  text-align: left;
  color: var(--text-2);
  font-size: var(--f-s);
  line-height: 1.2;
}
.ffp-font-btn:hover {
  background: var(--alpha-hover);
  color: var(--text-1);
}
.ffp-font-btn.active {
  background: var(--alpha-mid);
  color: var(--text-1);
  font-weight: 600;
}
.ffp-font-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--ring-action);
}

.popover-open {
  background: var(--alpha-mid) !important;
}

@keyframes hwr-pulse {
  0%, 100% { opacity: 0.5; }
  50%       { opacity: 0.9; }
}
.draw-hwr-btn.hwr-loading,
.draw-img-btn.hwr-loading {
  pointer-events: none;
  animation: hwr-pulse 1s ease-in-out infinite;
}

/* ── Conversion animations ───────────────────────────────────── */
@keyframes mb-burst-particle {
  0%   { transform: translate(0, 0) scale(1); opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(0.2); opacity: 0; }
}
.mb-burst-particle {
  position: fixed;
  border-radius: 50%;
  animation: mb-burst-particle 400ms ease-out forwards;
  pointer-events: none;
  z-index: var(--z-hwr-popup);
}

/* ── HWR recognised-text label (shown during draw-to-image fetch) ── */
.mb-hwr-text-label {
  position: fixed;
  display: flex;
  align-items: center;
  background: var(--card-bg);
  border: var(--border) solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--s) var(--ms);
  font-family: var(--font-sans);
  pointer-events: none;
  z-index: var(--z-hwr-popup);
  transform: translate(-50%, -110%);
  box-shadow: var(--shadow-sm);
  opacity: 1;
  transition: opacity 200ms ease; /* 200ms pairs with the 210ms setTimeout in hwr/recognizer.js and hwr/convert.js */
  white-space: nowrap;
}
.mb-hwr-label-text {
  font-size: var(--f-m);
  font-style: italic;
  color: var(--text-2);
  line-height: 1.3;
}
.mb-hwr-text-label.fade-out {
  opacity: 0;
}

/* ── Shared spinner animation (HWR indicator + search spinner) ── */
@keyframes mb-spinner-spin {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(360deg); }
}
.mb-hwr-indicator {
  position: fixed;
  width: var(--l);
  height: var(--l);
  border: var(--border-bold) solid var(--color-border);
  border-top-color: var(--color-action);
  border-radius: 50%;
  animation: mb-spinner-spin 0.7s linear infinite;
  pointer-events: none;
  z-index: var(--z-hwr-popup);
  opacity: 1;
  transition: opacity 200ms ease; /* 200ms pairs with the 210ms setTimeout in hwr/recognizer.js and hwr/convert.js */
}
.mb-hwr-indicator.fade-out {
  opacity: 0;
}

.cgrid-standard,
.cgrid-custom {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--xs);
}

.cgrid-swatch {
  aspect-ratio: 1;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  transition: transform var(--t-snap) ease, box-shadow var(--t-snap) ease;
  touch-action: manipulation;
  position: relative;
}
.cgrid-swatch.active {
  box-shadow: 0 0 0 var(--border-bold) var(--card-bg), 0 0 0 5px var(--color-action);
}
.cgrid-swatch.light {
  box-shadow: inset 0 0 0 var(--border) var(--color-border);
}
.cgrid-swatch.light.active {
  box-shadow:
    inset 0 0 0 var(--border) var(--color-border),
    0 0 0 var(--border-bold) var(--card-bg),
    0 0 0 5px var(--color-action);
}
.cgrid-swatch.empty {
  background: var(--card-bg);
  border: var(--border) dashed var(--color-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-3);
}
.cgrid-swatch.empty:hover { background: var(--alpha-hover); }

/* ── HWR result popup ── */
#hwr-result-popup {
  position: fixed;
  z-index: var(--z-hwr-popup);
  background: var(--card-bg);
  border: var(--border) solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: var(--s) var(--ms);
  min-width: 160px;
  max-width: 260px;
}

.hwr-result-text {
  margin: 0 0 var(--s);
  font-size: var(--f-s);
  font-weight: 500;
  word-break: break-word;
  color: var(--text-1);
}

.hwr-error {
  margin: 0 0 var(--ms);
  font-size: var(--f-s);
  color: var(--color-danger);
}

.hwr-btn-row {
  display: flex;
  gap: var(--s);
  justify-content: flex-end;
}

.hwr-convert-btn,
.hwr-cancel-btn {
  padding: var(--s) var(--ms);
  font-size: var(--f-s);
  font-weight: 600;
  white-space: nowrap;
}

.hwr-convert-btn {
  background: var(--color-action);
  color: var(--white);
  border-color: var(--color-action);
}

.hwr-cancel-btn {
  background: transparent;
  color: var(--text-1);
  border-color: var(--color-border);
}

.pick-btn {
  color: var(--text-3);
  font-size: var(--f-m);
  font-weight: 400;
  transition: background var(--t-snap) ease, box-shadow var(--t-snap) ease, color var(--t-snap) ease;
}

.pick-btn:hover {
  background: var(--alpha-hover);
  color: var(--text-2);
}

.pick-btn.active {
  background: var(--alpha-active);
  border-color: transparent;
}

.pick-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--ring-action);
}

/* 6×2 grid of swatch circles */
.picker-swatches {
  display: grid;
  grid-template-columns: repeat(6, var(--xxl));
  gap: var(--s);
  justify-content: space-between;
}

.picker-swatch {
  width: var(--xxl);
  height: var(--xxl);
  border-radius: 50%;
  border: none;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform var(--t-snap) ease, box-shadow var(--t-snap) ease;
}

.picker-swatch.active {
  box-shadow: 0 0 0 var(--border-bold) var(--card-bg), 0 0 0 5px var(--color-action);
}

.picker-swatch.light {
  box-shadow: inset 0 0 0 var(--border) var(--color-border);
}

.picker-swatch.light.active {
  box-shadow:
    inset 0 0 0 var(--border) var(--color-border),
    0 0 0 var(--border-bold) var(--card-bg),
    0 0 0 5px var(--color-action);
}

.picker-swatch:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--ring-action);
}

/* 6 custom colour slots — same grid as presets */
.picker-custom-slots {
  display: grid;
  grid-template-columns: repeat(6, 36px);
  gap: var(--s);
  margin-top: var(--ms);
  padding-top: var(--ms);
  border-top: var(--border) solid var(--color-border);
}

/* Empty slot: faint border, + icon */
.custom-slot.empty {
  background: transparent !important;
  border: var(--border) dashed var(--color-border) !important;
  color: var(--text-3);
  display: flex;
  align-items: center;
  justify-content: center;
}

.custom-slot.empty:hover {
  border-color: var(--color-action-bd) !important;
  color: var(--color-action);
}



/* ── Theme picker popup ── */
.theme-picker-popup {
  position: absolute;
  z-index: var(--z-picker);
  background: var(--card-bg);
  border: var(--border) solid var(--color-panel-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: var(--ms);
  width: 240px;
  pointer-events: none;
  opacity: 0;
  transform: translateY(var(--s)) scale(0.97);
  transition: opacity var(--t-fast) ease, transform var(--t-fast) ease;
}
.theme-picker-popup.open {
  pointer-events: auto;
  opacity: 1;
  transform: translateY(0) scale(1);
}

.theme-cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s);
}

.theme-card {
  border-radius: var(--radius);
  padding: var(--ms);
  cursor: pointer;
  border: var(--border-bold) solid transparent;
  touch-action: manipulation;
  transition: border-color var(--t-snap) ease, transform var(--t-snap) ease;
}
.theme-card.active { border-color: var(--color-action); }

.theme-card-name {
  font-size: var(--f-s);
  font-weight: 600;
  margin-bottom: var(--s);
  white-space: nowrap;
}
.theme-card-name.light-text { color: var(--white-a85); }
.theme-card-name.dark-text  { color: rgba(40,30,25,0.88); }

.theme-mini-dots {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--xs);
}
.theme-dot {
  width: var(--l);
  height: var(--l);
  border-radius: 50%;
  border: var(--border) solid var(--black-a10);
  flex-shrink: 0;
}
.theme-dot.light-dot { border-color: var(--black-a18); }



/* ─────────────────────────────────────────────────────────────────
   9. IMAGE SEARCH CONTROLS — rendered into .ftp-docked-panel
   ───────────────────────────────────────────────────────────────── */
.ts-row {
  display: flex;
  align-items: center;
  gap: var(--s);
}

.ts-sep {
  width: 1px;
  height: var(--l);
  background: var(--color-border);
  flex-shrink: 0;
}

.ts-type-group {
  display: flex;
  border: var(--border) solid var(--color-border);
  border-radius: var(--radius);
  overflow: hidden;
  flex-shrink: 0;
}

.ts-caption-label {
  display: flex;
  align-items: center;
  gap: var(--s);
  font-family: var(--font-sans);
  font-size: var(--f-s);
  color: var(--text-2);
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
  flex-shrink: 0;
}

.ts-caption-chk {
  width: var(--f-s);
  height: var(--f-s);
  accent-color: var(--color-action);
  cursor: pointer;
  flex-shrink: 0;
}

.ts-input {
  flex: 1;
  height: var(--xl);
  padding: 0 var(--s);
  border: var(--border) solid var(--color-border);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text-1);
  font-family: var(--font-sans);
  font-size: var(--f-m);
  width: 8rem;
}

.ts-input:focus {
  outline: none;
  border-color: var(--color-action-bd);
  box-shadow: 0 0 0 3px var(--ring-action-soft);
}

.ts-input::placeholder { color: var(--text-3); }

.ts-btn {
  border-color: var(--color-action);
  color: var(--color-action);
  transition: background var(--t-snap) ease;
}

.ts-btn:hover { background: var(--color-action-lt); }


/* Image type anchor — single button showing current type, opens popup */
.ts-type-anchor {
  gap: var(--s);
  border-color: var(--color-border);
  color: var(--text-2);
  font-size: var(--f-s);
  white-space: nowrap;
}
.ts-type-anchor:hover { background: var(--color-action-lt); color: var(--text-1); }

/* Image type popup */
.image-type-popup {
  width: auto !important;
  min-width: 120px;
  padding: var(--s) !important;
}
.itp-type-btn {
  display: flex;
  gap: var(--s);
  width: 100%;
  padding: var(--s) 14px;
  border-radius: var(--radius);
  color: var(--text-1);
  font-size: var(--f-m);
  white-space: nowrap;
  justify-content: flex-start;
}
.itp-type-btn:hover { background: var(--alpha-hover); }
.itp-type-btn.active { background: var(--color-action); color: #fff; }

/* Search spinner — fixed, positioned via JS */
#search-spinner {
  position: fixed;
  z-index: var(--z-panel);
  width: var(--l);
  height: var(--l);
  border: var(--border-bold) solid var(--color-border);
  border-top-color: var(--color-action);
  border-radius: 50%;
  animation: mb-spinner-spin 0.7s linear infinite;
  transform: translate(-50%, -50%);
}

#search-spinner[hidden] { display: none; }

/* More button in qi-thumb strip — matches mb-magic-btn colour scheme, sized for thumbnail row */
.qi-back-btn,
.qi-more-btn {
  display: inline-flex;
  flex-direction: column;
  gap: var(--xs);
  width: var(--4xl);
  height: var(--4xl);
  background: var(--bg-t);
  color: var(--color-action);
  font-size: var(--f-s);
  font-weight: 600;
  transition: background var(--t-snap) ease, transform var(--t-snap) ease;
}

.qi-back-btn:hover,
.qi-more-btn:hover {
  background: var(--color-action-lt-hover);
  border-color: var(--color-action-bd);
}

/* Loading state on panel */
.ofb-qi-section.loading { pointer-events: none; }

@keyframes qi-shimmer {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 0.15; }
}

.qi-thumb.qi-thumb-skeleton {
  position: relative;
  pointer-events: none;
  cursor: default;
}

.qi-thumb.qi-thumb-skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--black-a10);
  animation: qi-shimmer 1.5s ease-in-out infinite;
}

.qi-thumb > .qi-thumb-skeleton {
  position: absolute;
  inset: 0;
  background: var(--black-a10);
  animation: qi-shimmer 1.5s ease-in-out infinite;
}




/* ─────────────────────────────────────────────────────────────────
   10. TOAST NOTIFICATION
   Fixed, bottom-center, above toolbar. Slides up on show.
   ───────────────────────────────────────────────────────────────── */
#toast {
  position: fixed;
  bottom: var(--4xl);
  left: 50%;
  z-index: var(--z-toast);
  background: var(--card-bg);
  color: var(--text-1);
  border: var(--border) solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-xl);
  padding: var(--s) var(--l);
  font-size: var(--f-m);
  font-family: var(--font-sans);
  white-space: nowrap;
  pointer-events: none;
  /* Hidden state: below viewport + invisible */
  opacity: 0;
  transform: translateX(-50%) translateY(var(--s));
  transition:
    opacity 200ms ease-out,
    transform 200ms ease-out;
}

#toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: auto;
}

#toast.error {
  border-color: var(--color-warning-bd);
  color: var(--color-warning-dk);
}

.toast-action {
  margin-left: var(--m);
  background: none;
  border: none;
  padding: 0;
  font-size: var(--f-m);
  font-family: var(--font-sans);
  font-weight: 600;
  color: var(--color-accent);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: var(--xs);
}


/* ─────────────────────────────────────────────────────────────────
   11. HIDDEN FILE INPUT
   ───────────────────────────────────────────────────────────────── */
#file-input {
  display: none;
}


/* ─────────────────────────────────────────────────────────────────
   12a. QUICK IMAGE CONTROLS — rendered into .ofb-qi-section inside OFB
   ───────────────────────────────────────────────────────────────── */
.ofb-qi-section {
  display: flex;
  flex-direction: column;
  gap: var(--s);
}

/* Thumbs + more button row */
.qi-thumbs-row {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--s);
}

.qi-thumb {
  position: relative;
  width: var(--4xl);
  height: var(--4xl);
  flex-shrink: 0;
  border-radius: var(--radius);
  border: var(--border-bold) solid transparent;
  overflow: hidden;
  cursor: pointer;
  touch-action: manipulation;
  padding: 0;
  background: var(--bg-t);
  transition: border-color var(--t-snap) ease, transform var(--t-snap) ease;
}

.qi-thumb img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}

.qi-thumb:hover {
  border-color: var(--color-action-bd);
}

.qi-thumb.active {
  border-color: var(--color-action);
  box-shadow: 0 0 0 var(--border) var(--color-action);
}

/* Emoji results grid */
.qi-emoji-grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--xs);
  padding: var(--xs) 0 2px;
  max-width: 340px;
}

.qi-emoji-btn {
  border-color: var(--color-border);
  background: var(--card-bg);
  font-size: var(--f-l);
  line-height: 1;
  transition: border-color var(--t-snap) ease, transform var(--t-snap) ease, background var(--t-snap) ease;
  font-family: 'Segoe UI Emoji', 'Apple Color Emoji', sans-serif;
  border-radius: var(--s);
}

.qi-emoji-btn:hover {
  border-color: var(--color-action-bd);
  background: var(--color-action-lt);
}

.qi-emoji-btn.active {
  border-color: var(--color-action);
  box-shadow: 0 0 0 var(--border) var(--color-action);
}

.qi-attribution {
  align-self: flex-end;
  font-family: var(--font-sans);
  font-size: var(--f-xs);
  color: var(--text-3);
  text-decoration: none;
}
.qi-attribution:hover { color: var(--text-2); text-decoration: underline; }

/* ─────────────────────────────────────────────────────────────────
   12b. OBJECT FLOATING BLOCK
   Floats next to selected object. Stacks: [tool section] [action row]
   [qi section]. Re-rendered on every selection change.
   ───────────────────────────────────────────────────────────────── */
#object-floating-block {
  position: fixed;
  z-index: var(--z-panel);
  display: flex;
  flex-direction: column;
  gap: var(--xs);
  background: var(--card-bg-t);
  border: var(--border) solid var(--color-panel-border);
  border-radius: var(--radius-l);
  padding: var(--s);
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
}
#object-floating-block[hidden] { display: none; }

.ofb-tool-section,
.ofb-action-row {
  display: flex;
  align-items: center;
  gap: var(--xs);
}

.ofb-tool-section { flex-direction: column; align-items: stretch; }
/* When the tool section IS itself the row-panel (renderDrawControls etc.
   attach .tool-controls-row to the same element), two-class specificity wins. */
.ofb-tool-section.tool-controls-row { flex-direction: row; align-items: center; }


.oab-btn {
  display: inline-flex;
  color: var(--text-2);
  white-space: nowrap;
}
.oab-btn:hover { background: var(--alpha-hover); color: var(--text-1); }

.oab-delete {
  color: var(--color-warning);
}
.oab-delete:hover {
  background: var(--color-warning-lt);
  color: var(--color-warning-dk);
  border-color: var(--color-warning-bd);
}


.oab-layer {
  gap: var(--xs);
}
.oab-icon-btn {
  min-width: var(--l);
  height: var(--l);
  padding: 0;
  border-radius: 50%;
  color: var(--color-action);
}
.oab-icon-btn:hover { background: var(--color-action-lt); }

/* Query chip inside action bar */
.oab-query-chip {
  display: flex;
  align-items: center;
  gap: var(--xs);
  background: transparent;
  border: var(--border) solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--xs) var(--s) 2px var(--s);
}
.oab-query-label {
  font-size: var(--f-s);
  color: var(--text-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 160px;
  cursor: pointer;
}
.oab-query-label:hover { color: var(--text-1); }
.oab-query-input {
  font-size: var(--f-s);
  font-family: var(--font-sans);
  color: var(--text-1);
  background: transparent;
  border: none;
  outline: none;
  width: 130px;
  padding: 0;
}

.oab-lock.active {
  background: var(--color-action);
  color: var(--white);
}
.oab-lock.active:hover {
  background: var(--color-action);
  color: var(--white);
}

.oab-erase-bg {
  gap: var(--s);
}
.oab-erase-bg-lbl {
  font-size: var(--f-s);
  font-weight: 600;
  letter-spacing: 0.02em;
}

.oab-opacity-toggle {
  gap: var(--xs);
}
.oab-opacity-pct {
  font-size: var(--f-s);
  font-weight: 500;
}

/* Opacity floating subpanel */
.opacity-popup {
  position: fixed;
  z-index: var(--z-panel);
  display: none;
  align-items: center;
  gap: var(--s);
  padding: var(--s) var(--s);
  background: var(--card-bg);
  border: var(--border) solid var(--color-panel-border);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-lg);
}
.opacity-popup.open {
  display: flex;
}
.oab-opacity-toggle.popover-open {
  background: var(--color-action-lt);
  color: var(--color-action-dk);
  border-color: var(--color-action-bd);
}
.oab-opacity-slider {
  width: var(--4xl);
  height: var(--xs);
  cursor: pointer;
  accent-color: var(--color-action);
}
.oab-opacity-value {
  font-size: var(--f-s);
  color: var(--text-2);
  min-width: var(--xxl);
  text-align: right;
  font-variant-numeric: tabular-nums;
}


/* ─────────────────────────────────────────────────────────────────
   12c. TEXT ACTIONS CONTROLS — rendered into .ftp-docked-panel or ofb-tool-section
   ───────────────────────────────────────────────────────────────── */
.text-action-btn {
  display: inline-flex;
  color: var(--text-2);
  font-size: var(--f-s);
  font-weight: 500;
  white-space: nowrap;
}

.text-action-btn:hover {
  background: var(--alpha-hover);
  color: var(--text-1);
}

.text-action-btn.active {
  background: var(--alpha-active);
  border-color: transparent;
  box-shadow: none;
}

.text-action-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--ring-action);
}

.text-action-btn:disabled {
  opacity: 0.3;
  pointer-events: none;
}

/* Bold/italic labels */
.taw-bold   { font-weight: 700; font-size: var(--f-m); }
.taw-italic { font-style: italic; font-size: var(--f-m); }

/* Alignment button group wrapper. display:contents makes the wrapper invisible
   to flexbox so its children participate directly in the .tool-controls-row
   flex layout. JS toggles to display:none to hide the whole group.
   The divider inside must be styled explicitly because > selectors don't
   penetrate display:contents wrappers in the DOM tree. */
.taw-align-group { display: contents; }


/* ─────────────────────────────────────────────────────────────────
   13. CROP OVERLAY
   ───────────────────────────────────────────────────────────────── */

#crop-overlay {
  position: absolute;
  inset: 0;
  z-index: var(--z-crop-overlay);
  cursor: crosshair;
  touch-action: none;
}

#crop-draw-canvas {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

#crop-frame {
  position: absolute;
  box-shadow: 0 0 0 9999px var(--black-a50);
  border: var(--border-bold) solid #fff;
  cursor: move;
  box-sizing: border-box;
}

#crop-frame.circle { border-radius: 50%; }

.crop-handle {
  position: absolute;
  width: var(--m);
  height: var(--m);
  background: var(--white);
  border: var(--border-bold) solid var(--black-a50);
  border-radius: var(--radius);
  touch-action: none;
}

.crop-nw { top: -var(--s);  left: -var(--s);  cursor: nw-resize; }
.crop-n  { top: -var(--s);  left: calc(50% - var(--s)); cursor: n-resize; }
.crop-ne { top: -var(--s);  right: -var(--s); cursor: ne-resize; }
.crop-w  { top: calc(50% - var(--s)); left: -var(--s); cursor: w-resize; }
.crop-e  { top: calc(50% - var(--s)); right: -var(--s); cursor: e-resize; }
.crop-sw { bottom: -var(--s); left: -var(--s);  cursor: sw-resize; }
.crop-s  { bottom: -var(--s); left: calc(50% - var(--s)); cursor: s-resize; }
.crop-se { bottom: -var(--s); right: -var(--s); cursor: se-resize; }

#crop-freehand-hint {
  position: absolute;
  top: var(--ms);
  left: 50%;
  transform: translateX(-50%);
  background: var(--black-a50);
  color: var(--white);
  padding: var(--s) var(--m);
  border-radius: var(--l);
  font-size: var(--f-s);
  pointer-events: none;
  white-space: nowrap;
}

#crop-controls {
  position: absolute;
  bottom: var(--m);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: var(--ms);
  align-items: center;
  background: var(--card-bg);
  border-radius: var(--radius-l);
  padding: var(--s) var(--ms);
  box-shadow: var(--shadow-lg);
  white-space: nowrap;
}

#crop-mode-btns {
  display: flex;
  border: var(--border) solid var(--color-border);
  border-radius: var(--radius-l);
  overflow: hidden;
}

.crop-mode-btn {
  display: flex;
  gap: var(--s);
  padding: 0 13px;
  border-right: var(--border) solid var(--color-border);
  border-radius: 0;
  font-size: var(--f-s);
  color: var(--text-2);
  min-height: var(--xxl);
}
.crop-mode-btn:last-child { border-right: none; }
.crop-mode-btn:hover {
  background: var(--alpha-hover);
  color: var(--text-1);
}
.crop-mode-btn.active {
  background: var(--color-action-lt);
  color: var(--color-action-dk);
}

#crop-action-btns {
  display: flex;
  gap: var(--s);
  margin-left: var(--s);
  border-left: var(--border) solid var(--color-border);
  padding-left: var(--ms);
}

.crop-action-btn {
  display: flex;
  gap: var(--s);
  width: auto;
  padding: 0 var(--m);
  border-color: var(--color-border);
  font-size: var(--f-s);
  min-height: var(--xxl);
  color: var(--text-2);
}
.crop-action-btn:hover {
  background: var(--alpha-hover);
  color: var(--text-1);
}
.crop-action-btn--primary {
  background: var(--color-success-lt);
  color: var(--color-success-dk);
  border-color: var(--color-success-bd);
}
.crop-action-btn--primary:hover {
  background: var(--color-success-lt-hover);
}


/* ─────────────────────────────────────────────────────────────────
   14. FLOATING TOOL PANEL (#ftp) — double-tap/click on empty canvas
   ───────────────────────────────────────────────────────────────── */

#ftp {
  position: fixed;
  z-index: var(--z-toolbar);
  background: var(--card-bg-t) ;
  border: var(--border) solid var(--color-panel-border);
  border-radius: var(--radius-l);
  box-shadow: var(--shadow-lg);
  padding: var(--s);
  touch-action: none;
}

body.mode-iwb #ftp {
  cursor: grab;
}

#ftp.ftp-dragging {
  cursor: grabbing;
  transition: none;
  user-select: none;
}

/* Docked panel — nested slot that holds the active tool's controls when no
   object is selected. Populated by updateToolPanels(); moves with the FTP. */
.ftp-docked-panel {
  margin-top: var(--s);
  padding-top: var(--s);
  border-top: var(--border) solid var(--color-panel-border);
  display: flex;
  flex-direction: column;
  gap: var(--xs);
  cursor: default;
}
.ftp-docked-panel[hidden] { display: none; }

/* Elements that are both docked-panel slot AND a single-row panel need the
   row direction. Two-class specificity wins over .ftp-docked-panel alone. */
.ftp-docked-panel.tool-controls-row { flex-direction: row; }

.ftp-row {
  display: flex;
  align-items: center;
  gap: var(--xs);
}

.ftp-tool-btn {
  height: var(--xxl);
  width: var(--xxl);
  color: var(--text-2);
}
.ftp-tool-btn:hover {
  background: var(--alpha-hover);
  color: var(--text-1);
}
.ftp-tool-btn.active {
  color: var(--card-bg);
  background: var(--text-1-t);
  box-shadow: none;
}


/* ─────────────────────────────────────────────────────────────────
   16. STROKE/FILL COLOUR PANEL POPUP
   ───────────────────────────────────────────────────────────────── */

.colour-panel-popup,
.widget-popup {
  display: flex;
  flex-direction: column;
  gap: var(--ms);
  position: absolute;
  z-index: var(--z-panel);
  background: var(--card-bg);
  border: var(--border) solid var(--color-panel-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: var(--m);
  pointer-events: none;
  opacity: 0;
  transform: translateY(var(--s)) scale(0.97);
  transition: opacity var(--t-fast) ease, transform var(--t-fast) ease;
}

.colour-panel-popup.open,
.widget-popup.open {
  pointer-events: auto;
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* ─────────────────────────────────────────────────────────────────
   18. FTP COLOUR BUTTONS
   ───────────────────────────────────────────────────────────────── */

/* FTP panel divider — adds center alignment (used in flex row context) */
.mb-divider--ftp {
  height: var(--l);
  align-self: center;
}

.ftp-colour-swatch {
  display: block;
  width: var(--l);
  height: var(--l);
  border-radius: 50%;
  border: var(--border-bold) solid var(--text-1-a18);
  flex-shrink: 0;
  transition: transform var(--t-snap) ease;
}

/* Stroke variant — ring: border shows the colour, centre is transparent */
.ftp-colour-swatch--stroke {
  background: transparent;
  border-width: var(--xs);
}

/* Fill variant — panel-bg border creates a gap, making the circle read as inset */
.ftp-colour-swatch--fill {
  border-color: var(--card-bg);
}

.ftp-colour-swatch.empty {
  background: var(--card-bg) !important;
  border: var(--border-bold) dashed var(--color-border);
}

/* Slashed swatch — means "no fill" / "no stroke" explicitly set.
   White backing (colour irrelevant when not applied); red diagonal with
   a white shadow so it stays visible on any swatch colour it overlays. */
.ftp-colour-swatch.none {
  background: var(--white) !important;
  border: var(--border-bold) solid var(--text-1-a45);
  position: relative;
  overflow: hidden;
}
.ftp-colour-swatch.none::after, .cp-none-btn::after {
  content: '';
  position: absolute;
  inset: var(--xs);
  background:
    linear-gradient(to top left,
      transparent calc(50% - var(--border-bold)),
      var(--white) calc(50% - 2.5px),
      #fff calc(50% - 1.5px),
      #e53935 calc(50% - 1.5px),
      #e53935 calc(50% + 1.5px),
      #fff calc(50% + 1.5px),
      #fff calc(50% + 2.5px),
      transparent calc(50% + var(--border-bold)));
}

/* "No fill" / "No stroke" button inside a colour palette popover.
   Sits next to the opacity slider. Highlighted when currently active. */
.cp-none-btn {
  display: inline-flex;
  width: var(--l);
  height: var(--l);
  border-color: var(--color-border);
  background: var(--white);
  padding: 0;
  position: relative;
  overflow: hidden;
  border-radius: var(--s);
}

.cp-none-btn.active {
  border-color: var(--color-action);
  box-shadow: 0 0 0 var(--border-bold) var(--color-action);
}

/* ── FTP dock toggle button ── */
#btn-ftp-dock {
  color: var(--text-3, var(--text-2));
  opacity: 0.65;
}
#btn-ftp-dock:hover {
  opacity: 1;
  background: var(--alpha-hover);
  color: var(--text-1);
}
#btn-ftp-dock.active {
  color: var(--text-1);
  opacity: 1;
  background: var(--alpha-active);
}



