/* ============================================================================
   Custom Rich Text Editor (RTE) styles
   Editor chrome (modal, toolbars, gutters) is scoped so it does not leak into the
   canvas. Content classes (gwe-rte-*) are shared by the editor and the published
   renderer so both look the same.
   ============================================================================ */

/* ---------- Modal shell ---------- */
.gwe-rte-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
}
.gwe-rte-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(3px);
}
.gwe-rte-modal {
  position: relative;
  width: 900px;
  max-width: 95vw;
  height: 82vh;
  display: flex;
  flex-direction: column;
  background: #1c1c1f;
  border-radius: 8px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  overflow: hidden;
  color: #eaeaea;
}
.gwe-rte-modal-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  background: #262629;
  border-bottom: 1px solid #333;
}

/* ---------- Top toolbar (holds insert + text-type + inline format) ---------- */
.gwe-rte-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 3px;
  padding: 6px 10px;
  background: #212124;
  border-bottom: 1px solid #333;
  position: sticky;
  top: 0;
  z-index: 25;
}
.gwe-rte-toolbar .relative { position: relative; }
.gwe-rte-toolbar-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  padding: 5px 9px;
  border-radius: 5px;
  color: #ddd;
  background: #313135;
}
.gwe-rte-toolbar-btn:hover { background: #3c3c42; }
.gwe-rte-toolbar-btn:disabled { opacity: 0.35; pointer-events: none; }

/* text-type dropdown trigger */
.gwe-rte-tb-type {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 118px;
  justify-content: space-between;
  font-size: 12.5px;
  padding: 6px 8px;
  border-radius: 6px;
  color: #eaeaea;
  background: #313135;
}
.gwe-rte-tb-type:hover { background: #3c3c42; }
.gwe-rte-tb-type:disabled { opacity: 0.4; }

/* generic toolbar popover */
.gwe-rte-tb-pop {
  position: absolute;
  z-index: 40;
  top: calc(100% + 6px);
  left: 0;
  background: #262629;
  border: 1px solid #3a3a3f;
  border-radius: 8px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
  padding: 6px;
}
.gwe-rte-type-pop { width: 180px; max-height: 320px; overflow-y: auto; }
.gwe-rte-type-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 6px 8px;
  border-radius: 5px;
  font-size: 13px;
  color: #ddd;
}
.gwe-rte-type-item:hover { background: #34343a; }
.gwe-rte-type-item.active { color: #60a5fa; background: #2f2f36; }

/* ---------- Body / canvas ---------- */
.gwe-rte-modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 24px clamp(16px, 5%, 56px);
  background: #161618;
}
/* The editing surface fills all available space (like the modal body). Left padding leaves
   room for the hover drag handle. */
.gwe-rte-canvas {
  width: 100%;
  min-height: 200px;
  padding: 6px 8px 32px 32px;
}

/* ---------- Editor core (shared by modal + inline collections) ---------- */
/* font-family: Inter here (not just on the popups listed further down under "UI chrome
   neutrality") because canvas mode renders this whole tree — toolbar included — INSIDE the
   published page's own iframe, where it would otherwise inherit the PROJECT's font by normal
   CSS inheritance (font-family cascades down from the iframe's body/:root) — modal/inline never
   had this problem since they render in the app's own document, which never carries the
   project's font at all. buildRteTypographyCss's own scoped rule (.gwe-rte-editor-body
   .gwe-rte-canvas / .gwe-rte-content) is more specific than this and correctly overrides it back
   to the project's font for the actual edited CONTENT — this only sets the baseline for
   everything else (toolbar, the type-picker popup below, …), which should never look like the
   site being edited. */
.gwe-rte-editor { display: flex; flex-direction: column; min-height: 0; font-family: Inter, sans-serif; }
.gwe-rte-editor-modal { flex: 1; }
.gwe-rte-editor-body { flex: 1; overflow-y: auto; min-height: 0; background: #161618; }
/* Inline (Collections) — self-contained bordered field, no popup. overflow stays visible so
   the toolbar's insert / text-type / color dropdowns are not clipped. */
.gwe-rte-editor-inline-wrap { border: 1px solid #3a3a3f; border-radius: 8px; background: #1c1c1f; }
.gwe-rte-editor-inline { border-radius: 8px; }
.gwe-rte-editor-inline .gwe-rte-toolbar { border-radius: 8px 8px 0 0; }
.gwe-rte-editor-inline .gwe-rte-editor-body { max-height: 55vh; background: #1c1c1f; border-radius: 0 0 8px 8px; }

/* Canvas (inline, in-place — no popup, no modal chrome): the content has to look pixel-identical
   to the non-editing render (RteRenderer), so nothing here may add box-model space around it —
   no padding, no background. The toolbar itself is no longer a descendant of
   .gwe-rte-editor-canvas at all — RteEditor.jsx portals it out to RteToolbarOverlay.jsx, in the
   parent document, coordinate-synced to this block the same way the canvas's own selection
   overlay is (see IFrame.jsx's measureEditingRichText) — so it can't get clipped by an ancestor's
   overflow:hidden or hidden behind the page's own header on scroll, both real problems when it
   floated inside the iframe. Its visual chrome lives in .gwe-rte-toolbar-portal below instead of
   here. */
/* display:block (overriding the base rule's flex, used to stack the toolbar above the body for
   the modal/inline variants): a flex container's own margin never collapses with its children's
   — margin-collapsing only happens in normal block flow. The toolbar isn't a sibling to lay out
   here anymore (see above), but flex would still trap the first/last block's own top/bottom
   margin as extra visible space inside the box instead of letting it collapse through and escape
   outside — which is what leaves a phantom gap above/below all the content that isn't there in
   the non-editing render. */
.gwe-rte-editor-canvas { position: relative; display: block; }
.gwe-rte-editor-canvas .gwe-rte-editor-body { background: transparent; overflow: visible; }
.gwe-rte-editor-canvas .gwe-rte-canvas { padding: 0; min-height: 0; }

/* The portaled toolbar's floating chrome (RteToolbarOverlay.jsx wraps it in a
   .gwe-rte-toolbar-portal div in the parent document — position/left/top there are inline styles
   driven by editingRichTextCoordinates, this only covers appearance). Resets the base rule's
   sticky positioning (meaningless once it's no longer a normal-flow sibling of the content it
   used to stick above) and adds the same floating-strip look .gwe-rte-media-toolbar uses. */
.gwe-rte-toolbar-portal .gwe-rte-toolbar {
  position: static;
  border: 1px solid #333;
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  white-space: nowrap;
}

.gwe-rte-original-ref { max-width: 720px; margin: 0 auto 16px; }
.gwe-rte-original-label { font-size: 11px; opacity: 0.5; margin-bottom: 4px; }
.gwe-rte-original-content {
  max-height: 160px;
  overflow: auto;
  padding: 10px;
  border: 1px solid #333;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.03);
  color: rgba(255, 255, 255, 0.6);
  font-size: 13px;
}

/* ---------- Block chrome (minimal hover-only drag handle) ---------- */
.gwe-rte-block-list { display: block; }
.gwe-rte-block {
  position: relative;
  border-radius: 5px;
  outline: none;
}
/* No padding here (was `1px 0`): a non-zero padding stops adjacent blocks' <p>/<h*> margins from
   collapsing through this wrapper into one shared gap the way plain sibling paragraphs would —
   each block ends up trapping its OWN full margin instead, doubling the visible gap between two
   consecutive blocks (e.g. two paragraphs each with margin:15px 0 collapse to a 15px gap normally,
   but render 30px apart once something in between blocks that collapse). The focus ring below
   doesn't need the padding either — outline-offset already pushes it outside the border box. */
/* Non-text blocks (divider/image/video/table/callout) have no text cursor of their own to show
   they're the active one — this ring is their only "Enter continues here" indicator. Text blocks
   never receive DOM focus on this wrapper (their own contentEditable does instead, via its own
   caret), so this selector never fires for them. */
.gwe-rte-block:focus {
  outline: 2px solid rgba(96, 165, 250, 0.6);
  outline-offset: 2px;
}
.gwe-rte-block-body { min-width: 0; }
/* handle sits in the frame's left padding, only on hover. Height is 1lh (its own font-size/
   line-height, set per block type in rteTypography.js) anchored to the block's top, so the
   flex-centered icon lands on the first line's vertical middle even when the block wraps to
   multiple lines or uses a much larger font (headings). */
.gwe-rte-block-handle {
  position: absolute;
  left: -20px;
  top: 0;
  height: 1lh;
  display: flex;
  align-items: center;
  opacity: 0;
  transition: opacity 0.1s;
}
.gwe-rte-block:hover > .gwe-rte-block-handle,
.gwe-rte-block-selected > .gwe-rte-block-handle { opacity: 1; }
.gwe-rte-drag-handle {
  width: 20px;
  height: 22px;
  display: grid;
  place-items: center;
  border-radius: 4px;
  color: #7a7a7a;
  cursor: grab;
}
.gwe-rte-drag-handle:hover { background: #2f2f34; color: #ddd; }
.gwe-rte-block-menu { top: 26px; }
.gwe-rte-ghost { opacity: 0.35; }

/* UI chrome neutrality — the block menu, table/media toolbars & settings, and upload
   placeholders all render INSIDE .gwe-rte-canvas (they're part of a block's own markup), so
   without this they'd inherit the project's font-family from rteTypography.js's `.gwe-rte-canvas`
   rule. These are editor UI, not edited content, so they stay on the editor's own UI font
   (matches :root in index.css) regardless of what typography the project configures. */
.gwe-rte-block-menu,
.gwe-rte-table-toolbar,
.gwe-rte-cell-toolbar,
.gwe-rte-media-toolbar,
.gwe-rte-media-settings,
.gwe-rte-image-empty,
.gwe-rte-video-empty,
.gwe-rte-link-tooltip,
.table-overlay-buttons {
  font-family: Inter, sans-serif;
}
/* Base positioning for the link-edit tooltip (RteLeaf.jsx's RteLinkLeaf) — normally the app's
   general-purpose `.tooltip`/`.tooltip-parent` utility (src/index.css) handles this, but that
   file is only ever bundled into the main document (imported from JS in main.jsx/App.jsx), never
   copied to a loadable stylesheet — so it never reaches the canvas iframe, which builds its own
   <head> from public/assets/css/*.css files only (IFrame.jsx). Without this, the tooltip rendered
   fine in the Collections modal/inline editor (main document) but sat unpositioned, inline in the
   text flow, in the canvas (confirmed live: `<span class="tooltip gwe-rte-link-tooltip ...">`
   computed `position: static` inside the iframe). Kept minimal — only the top/bottom-center
   variants RteLeaf.jsx actually uses, copied verbatim from src/index.css so the two stay visually
   identical; visibility itself is still JS-driven opacity/pointer-events (RteLeaf.jsx), not the
   :hover rule this omits. */
.tooltip-parent {
  position: relative;
}
.tooltip,
.tooltip.tooltip-top-center {
  --tooltip-bg: hsl(0, 0%, 40%);
  user-select: none;
  display: block;
  white-space: nowrap;
  font-size: 12px;
  color: #FFF;
  background: var(--tooltip-bg);
  padding: 0 8px;
  border-radius: 4px;
  line-height: 2;
  opacity: 0;
  pointer-events: none;
  position: absolute;
  left: 50%;
  top: -6px;
  z-index: 100;
  transform: translateX(-50%) translateY(-100%);
  transition: 0.3s;
  margin-bottom: 6px;
  box-shadow: 0 2px 3px 0 rgba(0,0,0,0.2), 0 0 15px 0 rgba(0,0,0,0.4);
}
.tooltip:after,
.tooltip.tooltip-top-center:after {
  content: '';
  border: 6px solid transparent;
  border-bottom: 0;
  border-top-color: var(--tooltip-bg);
  position: absolute;
  left: 50%;
  margin-left: -6px;
  bottom: -6px;
}
.tooltip.tooltip-bottom-center {
  top: auto;
  bottom: -12px;
  z-index: 100;
  transform: translateX(-50%) translateY(100%);
}
.tooltip.tooltip-bottom-center:after {
  border: 6px solid transparent;
  border-top: 0;
  border-bottom-color: var(--tooltip-bg);
  position: absolute;
  left: 50%;
  z-index: 100;
  margin-left: -6px;
  top: -6px;
  bottom: auto;
}

/* The tooltip also sits inside a leaf styled by the link's own marks (bold/italic/underline/
   color), which would otherwise inherit into it — reset it back to plain UI chrome. Layout is
   flex (overriding the generic .tooltip's block) to line up the label with the trailing edit
   icon on one line; visibility itself is JS-driven (see RteLeaf.jsx), this only sets its resting
   state. The doubled-up selector (rather than plain .gwe-rte-link-tooltip) matches .tooltip's own
   specificity so `display` reliably wins regardless of stylesheet order. `width: max-content`
   guards against the tooltip's own box getting width-collapsed: its positioned ancestor (the
   link `<a>`) is an INLINE element, and browsers are inconsistent about the containing block
   they compute for an absolutely positioned child of an inline box — it can end up as narrow as
   the link text itself, squeezing/wrapping the icon under the label. */
.tooltip.gwe-rte-link-tooltip {
  /* !important is required here, not just higher specificity: editor.css:787 has
     `[data-slate-node="element"] *{display:inline !important;}`, a blanket reset forcing every
     descendant of a Slate element node to `inline` (this tooltip sits inside the link's own
     Slate leaf). !important always wins over specificity regardless of selector weight, so no
     amount of extra classes here can out-rank it — only another !important can. Confirmed live:
     without this, the icon fell back to plain inline flow instead of being vertically centered
     next to the label (the exact "pencil icon misaligned" bug being fixed), even though this
     rule's own specificity already exceeds the reset's. */
  display: inline-flex !important;
  flex-wrap: nowrap;
  align-items: center;
  gap: 6px;
  width: max-content;
  white-space: nowrap;
  font-weight: 400;
  font-style: normal;
  text-decoration: none;
  cursor: pointer;
  /* .tooltip's own line-height:2/padding:0 8px is sized for plain single-line text — flex
     content (label + icon) doesn't need that much breathing room and reads as an oversized,
     boxy bubble for a two-word label. Tighter padding + line-height keep the same visual
     language (colors, shadow, arrow) but scale the box down to the icon's own size. */
  padding: 4px 10px;
  line-height: 1.4;
  border-radius: 6px;
}
/* The icon never shrinks/wraps away; the label truncates instead if it runs long. */
.gwe-rte-link-tooltip svg { flex-shrink: 0; opacity: 0.85; }
/* Scaled down to match the tighter bubble above — the base .tooltip:after arrow (6px) reads as
   oversized against this smaller box. Only overrides the two placements RteLeaf.jsx uses. */
.tooltip.gwe-rte-link-tooltip.tooltip-top-center:after {
  border-width: 5px;
  margin-left: -5px;
  bottom: -5px;
}
.tooltip.gwe-rte-link-tooltip.tooltip-bottom-center:after {
  border-width: 5px;
  margin-left: -5px;
  top: -5px;
}
.gwe-rte-link-tooltip-label {
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* toolbar icon button (shared with the old floating toolbar styles) */
.gwe-rte-tb-btn:disabled { opacity: 0.3; pointer-events: none; }

/* ---------- Insert menu / block menu ---------- */
.gwe-rte-insert-menu {
  position: absolute;
  z-index: 30;
  top: 24px;
  left: 0;
  width: 210px;
  max-height: 320px;
  overflow-y: auto;
  background: #262629;
  border: 1px solid #3a3a3f;
  border-radius: 7px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
  padding: 6px;
}
.gwe-rte-gutter-pop { left: 0; }
.gwe-rte-toolbar-pop { top: 30px; }
.gwe-rte-insert-group + .gwe-rte-insert-group { margin-top: 4px; }
.gwe-rte-insert-group-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.45; padding: 4px 6px 2px; }
.gwe-rte-insert-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 8px;
  border-radius: 5px;
  font-size: 13px;
  color: #ddd;
}
.gwe-rte-insert-item:hover { background: #34343a; }
.gwe-rte-insert-shortcut {
  margin-left: auto;
  padding-left: 10px;
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 11px;
  color: #777;
  white-space: nowrap;
}

/* "/" command menu — portaled to <body>, positioned in fixed viewport coords near the caret. */
.gwe-rte-slash-menu {
  position: fixed;
  z-index: 9999;
  width: 220px;
  max-height: 320px;
  overflow-y: auto;
  background: #262629;
  border: 1px solid #3a3a3f;
  border-radius: 7px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
  padding: 6px;
  font-family: Inter, sans-serif;
  transition: opacity 0.08s ease-out;
}
.gwe-rte-slash-empty { padding: 8px; font-size: 13px; color: #888; }
.gwe-rte-slash-item.active { background: #34343a; }

.gwe-rte-block-menu {
  position: absolute;
  z-index: 30;
  top: 24px;
  left: 0;
  width: 190px;
  background: #262629;
  border: 1px solid #3a3a3f;
  border-radius: 7px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
  padding: 6px;
}
.gwe-rte-menu-row { display: flex; gap: 2px; padding: 2px; }
.gwe-rte-menu-icon { padding: 5px; border-radius: 5px; color: #ccc; }
.gwe-rte-menu-icon:hover { background: #34343a; }
.gwe-rte-menu-label { display: flex; align-items: center; gap: 5px; font-size: 10px; text-transform: uppercase; opacity: 0.45; padding: 6px 6px 2px; }
.gwe-rte-menu-item { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px; border-radius: 5px; font-size: 13px; color: #ddd; }
.gwe-rte-menu-item:hover { background: #34343a; }
.gwe-rte-menu-danger:hover { color: #f87171; }
.gwe-rte-menu-sep { height: 1px; background: #3a3a3f; margin: 4px 0; }

/* ---------- Floating inline toolbar ---------- */
.gwe-rte-floating-toolbar {
  position: fixed;
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 1px;
  padding: 3px;
  background: #2b2b30;
  border: 1px solid #3d3d44;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.gwe-rte-tb-btn { padding: 5px; border-radius: 5px; color: #ddd; }
.gwe-rte-tb-btn:hover { background: #3a3a42; }
.gwe-rte-tb-btn.active { background: #3a3a42; color: #60a5fa; }
.gwe-rte-tb-sep { width: 1px; height: 18px; background: #48484f; margin: 0 3px; }
.gwe-rte-swatches { display: flex; gap: 4px; padding: 3px 5px; align-items: center; }
.gwe-rte-swatch { width: 18px; height: 18px; border-radius: 4px; border: 1px solid rgba(255, 255, 255, 0.15); }
.gwe-rte-swatch-none { display: grid; place-items: center; background: #333; color: #f87171; font-weight: bold; }

/* ---------- Link panel ---------- */
.gwe-rte-link-panel { display: flex; flex-direction: column; gap: 6px; padding: 8px; width: 270px; }
.gwe-rte-link-tabs { display: flex; background: #1c1c1f; border-radius: 6px; padding: 2px; gap: 2px; }
.gwe-rte-link-tab { flex: 1; padding: 5px; border-radius: 5px; font-size: 12px; color: #ccc; text-align: center; }
.gwe-rte-link-tab.active { background: #3a3a42; color: #fff; }
.gwe-rte-link-select { background: #1c1c1f; border: 1px solid #444; border-radius: 5px; padding: 6px 8px; font-size: 13px; color: #fff; width: 100%; }
.gwe-rte-link-url { background: #1c1c1f; border: 1px solid #444; border-radius: 5px; padding: 6px 8px; font-size: 13px; color: #fff; }
.gwe-rte-link-check { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #ccc; }
.gwe-rte-link-actions { display: flex; gap: 6px; justify-content: flex-end; }
.gwe-rte-link-apply, .gwe-rte-link-remove { padding: 5px; border-radius: 5px; background: #3a3a42; color: #fff; }
.gwe-rte-link-apply:disabled { opacity: 0.4; pointer-events: none; }
.gwe-rte-link-apply:hover { background: #2563eb; }
.gwe-rte-link-remove:hover { color: #f87171; }

/* ---------- Media toolbars / handles ---------- */
.gwe-rte-media-toolbar,
.gwe-rte-table-toolbar,
.gwe-rte-cell-toolbar {
  position: absolute;
  z-index: 20;
  top: -38px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 1px;
  padding: 3px;
  background: #2b2b30;
  border: 1px solid #3d3d44;
  border-radius: 7px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  color: #ddd;
  white-space: nowrap;
}
.gwe-rte-cell-toolbar { position: sticky; bottom: 6px; top: auto; left: 0; transform: none; display: inline-flex; margin-top: 6px; }
/* Portaled to the parent document (ImageBlock.jsx/VideoBlock.jsx/TableBlock.jsx,
   useRteFloatingPortal) inside a pointer-events:none wrapper — pointer-events:auto here is what
   makes it (and its children) clickable again. .gwe-rte-cell-toolbar doesn't need this: it isn't
   portaled (see its own rule just above — back to normal in-flow layout, sticky to the cell). */
.gwe-rte-media-toolbar, .gwe-rte-table-toolbar { pointer-events: auto; }
.gwe-rte-media-settings {
  position: absolute;
  z-index: 21;
  top: 6px;
  right: 6px;
  width: 220px;
  background: #262629;
  border: 1px solid #3a3a3f;
  border-radius: 7px;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 12px;
}
.gwe-rte-media-settings label { display: flex; flex-direction: column; gap: 3px; }
.gwe-rte-media-settings label.row { flex-direction: row; align-items: center; gap: 6px; }
.gwe-rte-media-settings input[type="text"],
.gwe-rte-media-settings input:not([type]),
.gwe-rte-media-settings select { background: #1c1c1f; border: 1px solid #444; border-radius: 4px; padding: 4px 6px; color: #fff; }

.gwe-rte-resize-handle { position: absolute; z-index: 15; background: #3b82f6; border: 1px solid #fff; border-radius: 2px; }
.gwe-rte-resize-handle.se { width: 12px; height: 12px; right: -6px; bottom: -6px; cursor: nwse-resize; }
.gwe-rte-resize-handle.e { width: 8px; height: 34px; right: -5px; top: 50%; transform: translateY(-50%); cursor: ew-resize; }
.gwe-rte-resize-handle.s { width: 34px; height: 8px; bottom: -5px; left: 50%; transform: translateX(-50%); cursor: ns-resize; }

/* ---------- Empty media placeholders ---------- */
.gwe-rte-image-empty, .gwe-rte-video-empty {
  border: 1px dashed #444;
  border-radius: 6px;
  padding: 22px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: #999;
  background: rgba(255, 255, 255, 0.02);
}
.gwe-rte-placeholder-btn { display: flex; flex-direction: column; align-items: center; gap: 6px; color: #bbb; }
.gwe-rte-placeholder-btn:hover { color: #fff; }
.gwe-rte-url-input { width: 100%; max-width: 460px; background: #1c1c1f; border: 1px solid #444; border-radius: 5px; padding: 7px 10px; color: #fff; font-size: 13px; }

/* ---------- Video aspect ratio ---------- */
.gwe-rte-video-ratio { position: relative; width: 100%; padding-top: 56.25%; }

/* ---------- Table editor chrome ---------- */
.gwe-rte-table-block { position: relative; }
/* Anchors the row/column add & delete teardrop overlay (TableBlock.jsx) — its buttons sit just
   outside the table's own box (negative right/bottom). Kept separate from .gwe-rte-table-scroll
   (which clips via overflow-x: auto for wide tables) so the overlay never gets clipped with it. */
.gwe-rte-table-wrap { position: relative; }
.gwe-rte-table-scroll { overflow-x: auto; }
/* A block nested inside a cell (see TableBlock.jsx's per-cell RteBlockList) draws its drag
   handle at left:-26px, same as everywhere else (.gwe-rte-block-handle) — past a cell's own
   10px padding that lands ~16px outside the cell's left border. Columns after the first still
   show it fine (it overlaps the previous cell, which isn't clipped), but the FIRST column has
   nothing to its left except .gwe-rte-table-scroll's own overflow-x:auto edge, which clips it.
   The width/padding/negative-margin combo below reserves 24px of unclipped room there WITHOUT
   moving or shrinking the table itself: the margin pulls the scroll box's edge left by 24px and
   the padding pushes its content back by the same 24px, netting zero visual change — but only
   under content-box sizing (width excludes padding). Everything here is border-box (see
   index.css's/editor.css's own reset), where width INCLUDES padding — so a bare `width:100%`
   left the box 24px narrower than the wrap it's in instead of net-zero, showing up as a phantom
   right margin on the whole table. calc(100% + 24px) compensates so the content area (width
   minus its own padding) still comes out to exactly 100%, same as before adding this pair. */
.gwe-rte-table-wrap .gwe-rte-table-scroll { width: calc(100% + 24px); padding-left: 24px; margin-left: -24px; }
/* Dashed cell guides on hover — outline (not border) so they overlay any borderStyle preset
   (none/horizontal/all) without affecting layout, and only while editing (not on the published
   site, which reuses .gwe-rte-table via RteRenderer.jsx but never gets this class). The outer
   outline is on .gwe-rte-table-wrap (not the table itself) because .gwe-rte-table-scroll clips
   anything drawn outside its box (overflow-x: auto), which would cut the table's own outline off.
   Both use the SAME 1px width (dash length/gap scale with outline-width, so mismatched widths
   render visibly different dash patterns) and outline-offset: -0.5px (half the width, negative)
   to center the ring exactly ON the border-box edge instead of hugging just outside it — that's
   what makes two adjacent cells' outlines land on the exact same pixels instead of stacking into
   a doubled-up line. Since two coincident cells' rings now overlap, each is drawn at half the
   target opacity (0.125) so the combined interior line reads at ~0.25, matching the (single-
   layer) exterior line on .gwe-rte-table-wrap. */
.gwe-rte-table-wrap:hover { outline: 1px dashed rgba(150, 150, 150, 0.125); outline-offset: -0.5px; }
.gwe-rte-table-editable:hover .gwe-rte-table-cell { outline: 1px dashed rgba(150, 150, 150, 0.125); outline-offset: -0.5px; }

/* Table toolbar/overlay chrome — hand-written instead of Tailwind utility classNames (which
   several block components still use inline, e.g. `className="absolute flex items-center..."`).
   That worked fine when this only ever rendered in the app's own document (modal/inline), where
   the app's Tailwind build is loaded — canvas mode renders it inside the canvas iframe instead,
   which never loads Tailwind's compiled output (only rte.css/editor.css/index.css, see
   IFrame.jsx), so every Tailwind class here silently did nothing: no position:absolute, no flex,
   no color, no z-index. Bare unstyled/unpositioned elements is why the row/column add-remove
   teardrops effectively didn't show up at all. */
.gwe-rte-icon-btn { padding: 4px; border-radius: 5px; color: #ddd; }
.gwe-rte-icon-btn:hover { background: #3a3a3f; }
.gwe-rte-icon-btn.active { background: #3a3a3f; color: #60a5fa; }
.gwe-rte-icon-btn.danger:hover { color: #f87171; }

.gwe-rte-table-toolbar-group { display: flex; align-items: center; gap: 2px; }

.gwe-rte-table-check-label {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  padding: 0 6px;
  color: #ddd;
  white-space: nowrap;
}
.gwe-rte-table-check-label + .gwe-rte-table-check-label { margin-left: 6px; }

.gwe-rte-table-overlay-wrap { position: absolute; pointer-events: none; z-index: 10; }
.gwe-rte-table-hover-zone { position: absolute; pointer-events: auto; }

.gwe-rte-table-teardrop {
  position: absolute;
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: bold;
}
.gwe-rte-table-teardrop-add { background: #3b82f6; color: #fff; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); }
.gwe-rte-table-teardrop-add:hover { background: #2563eb; }
.gwe-rte-table-teardrop-delete { background: transparent; color: #ef4444; }
.gwe-rte-table-teardrop-delete:hover { background: #ef4444; color: #fff; }

/* Row/column delete confirmation — replaces window.confirm (a native dialog is raw browser
   chrome, out of place next to everything else here, and a known source of flaky behavior in
   embedded/iframe contexts). Fixed width so the caller can position it predictably. */
.gwe-rte-table-confirm-pop {
  position: absolute;
  z-index: 41;
  width: 220px;
  background: #262629;
  border: 1px solid #3a3a3f;
  border-radius: 8px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
  padding: 10px;
  pointer-events: auto;
}
.gwe-rte-table-confirm-text { font-size: 12.5px; line-height: 1.4; color: #ddd; margin-bottom: 8px; }
.gwe-rte-table-confirm-actions { display: flex; justify-content: flex-end; gap: 6px; }
.gwe-rte-table-confirm-btn { font-size: 12px; padding: 4px 10px; border-radius: 5px; color: #ddd; background: #313135; }
.gwe-rte-table-confirm-btn:hover { background: #3c3c42; }
.gwe-rte-table-confirm-btn-danger { background: #ef4444; color: #fff; }
.gwe-rte-table-confirm-btn-danger:hover { background: #dc2626; }

/* ============================================================================
   Shared CONTENT styles (editor + renderer)
   ============================================================================ */
.gwe-rte-content > * + *,
.gwe-rte-block-body > * { }
.gwe-rte-editable:focus { outline: none; }
.gwe-rte-editable [data-slate-placeholder] { color: #666; opacity: 1 !important; }

.gwe-rte-paragraph { margin: 0.35em 0; line-height: 1.6; }
.gwe-rte-simple-text { margin: 0; line-height: 1.6; }
.gwe-rte-heading-1, .gwe-rte-h1-heading, .gwe-rte-block-text.gwe-rte-heading-1 { font-size: 2em; font-weight: 700; margin: 0.6em 0 0.3em; line-height: 1.15; }
.gwe-rte-heading-2 { font-size: 1.6em; font-weight: 700; margin: 0.55em 0 0.3em; line-height: 1.2; }
.gwe-rte-heading-3 { font-size: 1.3em; font-weight: 600; margin: 0.5em 0 0.25em; }
.gwe-rte-heading-4 { font-size: 1.15em; font-weight: 600; margin: 0.5em 0 0.25em; }
.gwe-rte-heading-5 { font-size: 1em; font-weight: 600; margin: 0.5em 0 0.25em; }
.gwe-rte-heading-6 { font-size: 0.9em; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; margin: 0.5em 0 0.25em; }
.gwe-rte-list { margin: 0.4em 0; padding-inline-start: 1.4em; list-style: disc; }
ol.gwe-rte-list { list-style: decimal; }
.gwe-rte-list-item { margin: 0.15em 0; }
/* .gwe-line gives the divider its color/thickness/width vars (--hr-color/--hr-height/--hr-width)
   for free, but its own height/border/margin are sized for the standalone "Línea" canvas widget
   — a 12px transparent border top+bottom (drop-target padding) plus 16px margin, which reads as
   one thick bar instead of a thin rule inside running text. The compound selector below
   (specificity 0,2,0, beats .gwe-line's 0,1,0 regardless of stylesheet order) collapses that back
   down to a plain line: height is just the configurable thickness, no border spacer, and margin
   matches a normal paragraph gap instead of the widget's fixed 16px.
   --text-color-auto is redeclared too (same trick: 0,2,0 wins over .gwe-line's 0,1,0 regardless
   of file order), because .gwe-line's own default composition of it —
   rgba(var(--text-color), var(--text-color-alpha)) — assumes --text-color is three bare
   comma-separated numbers. --text-color-alpha is always 1 (not itself stylable anywhere), so
   that composition is only ever "currentColor with extra steps" — except in a context whose
   --text-color is instead a full color string (e.g. rgba(255,255,255,0.87), as set in the
   Collections popup / other inline-editing chrome outside the canvas), where the nested rgba()
   is invalid CSS. Once --hr-color (.gwe-line's rule) is declared as var(--text-color-auto),
   var()'s fallback machinery can't rescue it either: a var() fallback only fires when the
   referenced property is entirely UNSET, and --text-color-auto/--hr-color both very much ARE
   set here, just to something that fails to parse — so background-color silently resolved to
   its transparent initial value instead of even .gwe-line's own rgba(0,0,0,0.5) fallback,
   verified empirically in that context. Overriding --text-color-auto straight to the
   currentColor keyword sidesteps the whole fragile composition (equivalent to it whenever
   --text-color IS well-formed, since the alpha multiplier is always 1 anyway) without touching
   --hr-color directly, so an explicit --hr-color override (e.g. a future StyleManager field)
   still wins over both this and .gwe-line's default exactly as before. */
.gwe-line.gwe-rte-divider {
  height: var(--hr-height, 1px);
  --text-color-auto: currentColor;
  border: none;
  margin: 1em 0;
}
/* Editor only. First attempt moved this 1em gap from the hr's margin to padding on the wrap, so
   it'd be part of .gwe-rte-block's clickable box instead of dead margin space — but margin
   collapses with the neighboring block's own margin (giving 1em total, same as read-only's bare
   <hr>) while padding doesn't collapse with anything, so edit mode ended up with strictly MORE
   total space than read-only (the neighbor's margin no longer had anything to collapse into).
   Left the hr's margin untouched instead (identical layout/collapsing to read-only, always) and
   widen the click target with an absolutely-positioned, out-of-flow hit-area layered on top —
   it can't affect layout or collapse anything since position:absolute removes it from flow
   entirely. See DividerBlock.jsx for the element this styles. */
.gwe-rte-divider-wrap { position: relative; }
.gwe-rte-divider-hit { position: absolute; inset: -14px 0; cursor: pointer; }
.gwe-rte-callout { border-radius: 8px; padding: 12px 14px; margin: 0.6em 0; position: relative; }
/* Variant backgrounds — all tinted the same way here, including 'simple' (the project's global
   "Tarjetas"/Card color, --clr-card, rather than an accent color). This file loads everywhere,
   including the Collections popup, where the callout is a generic content-editing card, not a
   WYSIWYG preview of the page — a translucent tint reads fine there for every variant. The
   literal hex after the comma in each is the seeder's own default for that color, used only when
   a project doesn't have it defined. None of these set --text-color: a contrast computed for the
   FULL accent/card color can read wrong once that color is diluted to a tint over an
   unpredictable page background, so they all keep whatever color the surrounding content already
   had (unchanged from before) — see rte-canvas-colors.css for the full-opacity, exact-global-
   color versions (including 'simple') used instead inside the canvas iframe, where that contrast
   guess IS accurate. */
.gwe-rte-callout[data-variant="simple"] { background: color-mix(in srgb, var(--clr-card, #FFFFFF) 35%, transparent); }
.gwe-rte-callout[data-variant="info"] { background: color-mix(in srgb, var(--clr-info, #B3E5FC) 35%, transparent); }
.gwe-rte-callout[data-variant="warning"] { background: color-mix(in srgb, var(--clr-warning, #FFECB3) 35%, transparent); }
.gwe-rte-callout[data-variant="success"] { background: color-mix(in srgb, var(--clr-success, #43A047) 18%, transparent); }
.gwe-rte-callout[data-variant="error"] { background: color-mix(in srgb, var(--clr-error, #C62828) 15%, transparent); }
/* The tinted (color-mix) versions above are the DEFAULT everywhere this file loads, including
   the app's own parent document (Collections' edit popup) — there the callout is just a generic
   content card, not a WYSIWYG preview of the page, and --clr-* isn't even defined outside the
   canvas iframe. The full-opacity, exact-global-color override for anything actually rendered
   inside the canvas iframe (editing or read-only, static or collection-sourced) lives in
   rte-canvas-colors.css instead — loaded only by IFrame.jsx, after this file, so it wins on
   source order despite equal selector specificity. See that file's header for why it's a
   separate stylesheet rather than a class scope here. */

/* Variant picker — a small toolbar shown above the card only while it's selected, matching the
   image/video block toolbars' floating-strip style (see .gwe-rte-media-toolbar). Portaled to the
   parent document (CalloutBlock.jsx, useRteFloatingPortal) inside a pointer-events:none wrapper —
   pointer-events:auto here is what makes it (and its children) clickable again. */
.gwe-rte-callout-toolbar { position: absolute; top: -34px; left: 0; z-index: 5; pointer-events: auto; }
.gwe-rte-callout-variant-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 9px;
  border-radius: 6px;
  background: #262629;
  border: 1px solid #3a3a3f;
  color: #ddd;
  font-size: 12.5px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.gwe-rte-callout-variant-btn:hover { background: #2f2f34; }
.gwe-rte-callout-variant-menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 6;
  width: 170px;
  background: #262629;
  border: 1px solid #3a3a3f;
  border-radius: 7px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
  padding: 6px;
}
.gwe-rte-callout-variant-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 8px;
  border-radius: 5px;
  font-size: 13px;
  color: #ddd;
}
.gwe-rte-callout-variant-item:hover { background: #34343a; }
.gwe-rte-callout-variant-item.active { color: #60a5fa; background: #2f2f36; }
.gwe-rte-callout-swatch { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; border: 1px solid rgba(255, 255, 255, 0.15); }
.gwe-rte-callout-swatch-simple { background: rgba(120, 120, 120, 0.5); }
.gwe-rte-callout-swatch-info { background: var(--clr-info, #B3E5FC); }
.gwe-rte-callout-swatch-warning { background: var(--clr-warning, #FFECB3); }
.gwe-rte-callout-swatch-success { background: var(--clr-success, #43A047); }
.gwe-rte-callout-swatch-error { background: var(--clr-error, #C62828); }
.gwe-rte-inline-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.9em; background: rgba(135, 135, 135, 0.22); padding: 0.1em 0.35em; border-radius: 4px; }
.gwe-rte-image-caption { font-size: 0.85em; opacity: 0.7; margin-top: 6px; }
.gwe-rte-image-block, .gwe-rte-video-block { margin: 0.6em 0; }
.gwe-rte-table { font-size: 0.95em; }
.gwe-rte-table-cell { min-width: 60px; padding: 10px; }

/* .gwe-table / .gwe-table-cell / .gwe-line — the canvas "Tabla"/"Línea" widgets' own default
   styles (TableComponent.jsx/LineComponent.jsx), which TableBlock.jsx/DividerBlock.jsx/
   RteRenderer.jsx now also tag their table/cell/hr elements with so an RTE table or divider
   matches an unstyled canvas widget, and picks up the same global --table-*/--hr-* overrides.
   Canvas mode and the published site load rte.css THEN public/assets/css/index.css (which
   defines the same selectors, see index.css's own .gwe-table/.gwe-line rules — its later-loaded
   copy just harmlessly re-wins with identical values there). But the Collections popup and any
   other inline/modal RTE render directly in the main app shell, which bundles a DIFFERENT
   index.css (src/index.css) that never defines .gwe-table/.gwe-line at all — without a copy
   here, those elements silently got no border/padding/table-layout/background at all in that
   context (the divider in particular rendered fully invisible: no rule meant background-color
   fell to its transparent initial value instead of even .gwe-line's own rgba(0,0,0,0.5)
   fallback). rte.css is the one file every context loads, so this copy is the actual common
   denominator — keep it byte-identical to index.css's version if that one changes. */
.gwe-table {
  width: 100%;
  table-layout: var(--table-layout, fixed);
  border-collapse: collapse;
  min-width: var(--table-min-width, none);
}
.gwe-table-cell {
  border-width: var(--table-border-width, 1px);
  border-color: var(--table-border-color, currentColor);
  border-style: solid;
  padding: var(--table-gap, 10px);
}
.gwe-table th.gwe-table-cell {
  background-color: var(--table-heading-color, transparent);
  --text-color: var(--table-heading-text-color, currentColor);
  text-align: inherit;
  font-weight: inherit;
}
.gwe-line {
  --text-color-alpha: 1;
  --hr-border: 12px;
  --text-color-auto: rgba(var(--text-color), var(--text-color-alpha));
  --hr-color: var(--text-color-auto);
  max-width: var(--hr-width, 100%);
  background-color: var(--hr-color, rgba(0, 0, 0, 0.5));
  height: calc(var(--hr-border, 5px) + var(--hr-border, 5px) + var(--hr-height, 1px));
  border-top: var(--hr-border) solid transparent;
  border-bottom: var(--hr-border) solid transparent;
  border-left: 0;
  border-right: 0;
  background-clip: padding-box;
  margin-block: 16px;
}

.gwe-rte-link { color: #3b82f6; text-decoration: underline; cursor: pointer; }
.gwe-rte-link-button { display: inline-block; text-decoration: none; }
