mirror of
https://github.com/hxuanwang/obsidian-cdrawer.git
synced 2026-07-22 08:32:59 +00:00
799 lines
20 KiB
CSS
799 lines
20 KiB
CSS
/* cdrawer styles */
|
|
|
|
/* Live percentage readout next to the label-size slider in settings.
|
|
SliderComponent's built-in value display (setDisplayFormat) is gated to
|
|
Obsidian 1.13.0, above this plugin's minAppVersion, so we render it manually. */
|
|
.cd-setting-value {
|
|
min-width: 3.5em;
|
|
text-align: right;
|
|
font-variant-numeric: tabular-nums;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.cd-diagram-svg {
|
|
display: inline-block;
|
|
background: transparent;
|
|
cursor: pointer;
|
|
/* Strokes inside the SVG use currentColor — track the theme like native math (§6.4). */
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
/* Label container inside the SVG's foreignObject (render.ts). */
|
|
.cd-rendered-label {
|
|
display: inline-block;
|
|
line-height: 1.2;
|
|
color: var(--text-normal);
|
|
}
|
|
|
|
.cd-diagram-wrap {
|
|
display: block;
|
|
margin: 0.25em auto;
|
|
text-align: center;
|
|
}
|
|
|
|
.cd-diagram-wrap .cd-diagram-svg {
|
|
/* Center the SVG within the reading column instead of left-aligning it. */
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.cd-error {
|
|
display: inline-block;
|
|
padding: 0.2em 0.5em;
|
|
color: var(--text-error);
|
|
background: var(--background-modifier-error);
|
|
border-radius: 4px;
|
|
font-family: var(--font-monospace);
|
|
font-size: 0.85em;
|
|
}
|
|
|
|
/* Floating grid editor overlay */
|
|
.cd-editor-overlay {
|
|
position: fixed;
|
|
z-index: 1000;
|
|
background: var(--background-primary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 8px;
|
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
|
|
padding: 12px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
font-size: var(--font-ui-small);
|
|
color: var(--text-normal);
|
|
/* Wide enough to be a comfortable editing surface: ~90% of the viewport,
|
|
capped so it never touches the window edges. §7.3. No overflow here — the
|
|
resize handles sit outside the box (negative offsets) and would be clipped
|
|
by overflow:auto. Scrolling lives on the inner body. */
|
|
width: min(900px, 90vw);
|
|
max-width: 95vw;
|
|
max-height: 90vh;
|
|
overflow: visible;
|
|
}
|
|
|
|
/* Scrollable inner content (chrome + grid + preview). */
|
|
.cd-editor-body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
overflow: auto;
|
|
min-height: 0;
|
|
}
|
|
|
|
/* Embedded mode (feature #1): de-chrome the overlay so the grid reads as part
|
|
of the page rather than a popup window. Drop the border, shadow, rounded
|
|
corners, and the viewport-relative max-size caps. Width is set in JS to match
|
|
the diagram's full-width wrapper (the reading column), so the grid aligns
|
|
with the page; height is content-driven. The grid surface itself keeps its
|
|
recessed panel so cells stay legible. */
|
|
.cd-editor-overlay.cd-editor-embedded {
|
|
background: transparent;
|
|
border: none;
|
|
border-radius: 0;
|
|
box-shadow: none;
|
|
padding: 4px;
|
|
max-width: 98vw;
|
|
max-height: none;
|
|
}
|
|
|
|
/* For a fresh insert (no diagram to track), embedded mode has no JS width set,
|
|
so fall back to the reading-column width the host would have used. */
|
|
.cd-editor-overlay.cd-editor-embedded:not(.cd-editor-inflow):not([style*="width"]) {
|
|
width: min(700px, 92vw);
|
|
}
|
|
|
|
/* In-flow embedded editor (feature #1): the root is mounted INSIDE the
|
|
diagram's wrapper as a normal block, so it occupies real layout space and the
|
|
page text reflows around it — no overlap. Override .cd-editor-overlay's
|
|
position:fixed and stretch to the wrapper's full width. */
|
|
.cd-editor-overlay.cd-editor-inflow {
|
|
position: static;
|
|
width: 100%;
|
|
z-index: auto;
|
|
}
|
|
|
|
.cd-editor-chrome {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 8px;
|
|
}
|
|
|
|
/* A draggable handle (the editor chrome bar and the properties-panel header).
|
|
The grabbing cursor is applied via the .is-dragging class while a drag is in
|
|
progress, since the drag continues on window-level listeners after the
|
|
pointer leaves the handle (where :active would stop applying). */
|
|
.cd-drag-handle {
|
|
cursor: grab;
|
|
}
|
|
|
|
.cd-drag-handle.is-dragging {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
.cd-editor-title {
|
|
font-weight: 600;
|
|
}
|
|
|
|
.cd-editor-actions {
|
|
display: flex;
|
|
gap: 6px;
|
|
}
|
|
|
|
.cd-editor-grid {
|
|
display: grid;
|
|
gap: 4px;
|
|
position: relative;
|
|
/* A clearly recessed surface behind the cells. In dark themes the standard
|
|
background vars are too close in value to separate the two layers, so we
|
|
darken the grid further with a semi-transparent black wash and a stronger
|
|
inset border for unambiguous contrast. */
|
|
background:
|
|
linear-gradient(rgba(0, 0, 0, 0.28), rgba(0, 0, 0, 0.28)),
|
|
var(--background-secondary-alt, var(--background-secondary));
|
|
padding: 18px 6px 6px 18px;
|
|
border-radius: 4px;
|
|
box-shadow: inset 0 0 0 1px var(--background-modifier-border-hover);
|
|
}
|
|
|
|
.cd-cell {
|
|
position: relative;
|
|
min-width: 92px;
|
|
min-height: 48px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
/* Cells sit on the grid surface as their own raised panel. */
|
|
background: var(--background-primary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 4px;
|
|
cursor: text;
|
|
padding: 4px 8px;
|
|
user-select: none;
|
|
}
|
|
|
|
/* In dark themes, lift the cells a touch so they read as the top layer
|
|
against the darkened grid. The :where() keeps specificity at zero so theme
|
|
overrides still win. */
|
|
.theme-dark .cd-cell {
|
|
background: var(--background-primary);
|
|
box-shadow: 0 0 0 1px var(--background-modifier-border);
|
|
}
|
|
|
|
/* Empty cells: a more visible dashed outline so the grid scaffold reads
|
|
clearly in both light and dark themes. */
|
|
.cd-cell.is-empty {
|
|
border-style: dashed;
|
|
opacity: 0.85;
|
|
}
|
|
|
|
.cd-cell.is-focused {
|
|
border-color: var(--interactive-accent);
|
|
box-shadow: 0 0 0 2px var(--interactive-accent-hover);
|
|
}
|
|
|
|
.cd-cell-label {
|
|
pointer-events: none;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.cd-cell-input {
|
|
position: absolute;
|
|
inset: 4px 8px;
|
|
border: none;
|
|
background: transparent;
|
|
color: var(--text-normal);
|
|
font: inherit;
|
|
outline: none;
|
|
text-align: center;
|
|
z-index: 2;
|
|
}
|
|
|
|
.cd-cell-preview {
|
|
pointer-events: none;
|
|
max-width: 100%;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.cd-col-header,
|
|
.cd-row-header {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 0.7em;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.cd-add-btn {
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: 1px dashed var(--background-modifier-border);
|
|
border-radius: 4px;
|
|
background: transparent;
|
|
color: var(--text-muted);
|
|
padding: 0 6px;
|
|
min-width: 20px;
|
|
min-height: 20px;
|
|
}
|
|
|
|
.cd-add-btn:hover {
|
|
color: var(--interactive-accent);
|
|
border-color: var(--interactive-accent);
|
|
}
|
|
|
|
.cd-remove-btn {
|
|
position: absolute;
|
|
top: -2px;
|
|
right: -2px;
|
|
width: 14px;
|
|
height: 14px;
|
|
border-radius: 50%;
|
|
background: var(--background-modifier-error);
|
|
color: var(--text-on-accent);
|
|
border: none;
|
|
font-size: 10px;
|
|
line-height: 1;
|
|
cursor: pointer;
|
|
display: none;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0;
|
|
}
|
|
|
|
.cd-col-header:hover .cd-remove-btn,
|
|
.cd-row-header:hover .cd-remove-btn {
|
|
display: flex;
|
|
}
|
|
|
|
.cd-svg-layer {
|
|
position: absolute;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
overflow: visible;
|
|
}
|
|
|
|
.cd-arrow-path {
|
|
fill: none;
|
|
stroke: var(--text-normal);
|
|
stroke-width: 1;
|
|
pointer-events: stroke;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Arrow group is clickable in both the grid editor and the live preview
|
|
(both attach .cd-arrow). State here in CSS rather than per-element styles. */
|
|
.cd-arrow {
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Selected arrow (feature #2): a clear accent-color highlight on the whole
|
|
arrow — shaft, head, and any tail decoration (hook/mapsto) all carry
|
|
.cd-arrow-path, so this one rule highlights the entire arrow, not just the
|
|
shaft. Applies in both the in-grid view and the live preview (both attach
|
|
.cd-arrow + .is-selected). The thicker stroke makes the selection obvious at
|
|
a glance even among overlapping parallel arrows. */
|
|
.cd-arrow.is-selected .cd-arrow-path {
|
|
stroke: var(--interactive-accent);
|
|
stroke-width: 2;
|
|
}
|
|
|
|
.cd-arrow-hit {
|
|
fill: none;
|
|
stroke: transparent;
|
|
stroke-width: 12;
|
|
pointer-events: stroke;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.cd-arrow-label {
|
|
font-size: 0.85em;
|
|
fill: var(--text-normal);
|
|
}
|
|
|
|
.cd-properties {
|
|
position: fixed;
|
|
z-index: 1002;
|
|
background: var(--background-primary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 6px;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
|
padding: 8px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
font-size: var(--font-ui-smaller);
|
|
min-width: 200px;
|
|
}
|
|
|
|
/* Draggable title bar for the arrow properties panel. */
|
|
.cd-properties-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin: -8px -8px 2px;
|
|
padding: 5px 8px;
|
|
border-bottom: 1px solid var(--background-modifier-border);
|
|
font-weight: 600;
|
|
cursor: grab;
|
|
user-select: none;
|
|
touch-action: none;
|
|
}
|
|
|
|
.cd-properties-header:active {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
/* Close button on the arrow-properties header (improvement #4). */
|
|
.cd-properties-close {
|
|
width: 18px;
|
|
height: 18px;
|
|
padding: 0;
|
|
margin-left: 4px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background: transparent;
|
|
color: var(--text-muted);
|
|
font-size: 16px;
|
|
line-height: 1;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.cd-properties-close:hover {
|
|
color: var(--text-error);
|
|
background: var(--background-modifier-error);
|
|
}
|
|
|
|
.cd-properties label {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
}
|
|
|
|
.cd-properties .cd-prop-row {
|
|
display: flex;
|
|
gap: 6px;
|
|
align-items: center;
|
|
}
|
|
|
|
/* Curve row: label, a range slider, and a live percent readout. */
|
|
.cd-properties .cd-curve-row {
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.cd-properties .cd-curve-row input[type="range"] {
|
|
flex: 1;
|
|
min-width: 80px;
|
|
}
|
|
|
|
.cd-properties .cd-curve-value {
|
|
min-width: 4em;
|
|
text-align: right;
|
|
color: var(--text-muted);
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.cd-properties .cd-curve-straighten {
|
|
align-self: flex-start;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background: transparent;
|
|
color: var(--text-muted);
|
|
border: 1px solid var(--background-modifier-border);
|
|
cursor: pointer;
|
|
font-size: var(--font-ui-smaller);
|
|
}
|
|
|
|
.cd-properties .cd-curve-straighten:hover {
|
|
color: var(--interactive-accent);
|
|
border-color: var(--interactive-accent);
|
|
}
|
|
|
|
/* Draggable curve handle on a selected grid arrow: a small dot at the arc
|
|
apex. Drag it perpendicular to the shaft to set the curve. */
|
|
.cd-curve-handle {
|
|
fill: var(--interactive-accent);
|
|
stroke: var(--background-primary);
|
|
stroke-width: 1.5;
|
|
cursor: ew-resize;
|
|
pointer-events: auto;
|
|
}
|
|
|
|
.cd-curve-handle:hover {
|
|
fill: var(--interactive-accent-hover);
|
|
}
|
|
|
|
.cd-properties input[type="text"],
|
|
.cd-properties select {
|
|
width: 100%;
|
|
}
|
|
|
|
.cd-drag-line {
|
|
fill: none;
|
|
stroke: var(--interactive-accent);
|
|
stroke-width: 1;
|
|
stroke-dasharray: 3 3;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Arrow-drag handle band around cells. Sits on top of the cell and captures
|
|
the press that begins a drag-to-draw-arrow gesture (or, on a click in place,
|
|
opens the label editor). When a cell is being edited, its input rises above
|
|
the band (z-index) so typing works normally. */
|
|
.cd-cell-drag-band {
|
|
position: absolute;
|
|
inset: 0;
|
|
pointer-events: auto;
|
|
cursor: crosshair;
|
|
}
|
|
|
|
/* --- Phase 2: floating grid editor extras --- */
|
|
|
|
.cd-editor-discard {
|
|
font-size: var(--font-ui-smaller);
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background: transparent;
|
|
color: var(--text-muted);
|
|
border: 1px solid var(--background-modifier-border);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.cd-editor-discard:hover {
|
|
color: var(--text-error);
|
|
border-color: var(--background-modifier-error);
|
|
}
|
|
|
|
/* Delete-diagram button (feature #2): same weight as Discard but always
|
|
error-toned, since it removes the diagram from the note (vs. Discard, which
|
|
only abandons the edit session). */
|
|
.cd-editor-delete {
|
|
font-size: var(--font-ui-smaller);
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background: transparent;
|
|
color: var(--text-error);
|
|
border: 1px solid var(--background-modifier-error);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.cd-editor-delete:hover {
|
|
background: var(--background-modifier-error);
|
|
color: var(--text-on-accent);
|
|
}
|
|
|
|
/* A selected arrow's label is draggable to reposition it (feature #3). The
|
|
foreignObject carries this class; its inner label keeps the grab cursor. */
|
|
.cd-arrow-label-drag {
|
|
cursor: grab;
|
|
}
|
|
|
|
.cd-arrow-label-drag:active {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
/* Import / Export chrome buttons (§9). Same weight as Discard so the three
|
|
read as one action row. */
|
|
.cd-editor-chrome-btn {
|
|
font-size: var(--font-ui-smaller);
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background: transparent;
|
|
color: var(--text-normal);
|
|
border: 1px solid var(--background-modifier-border);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.cd-editor-chrome-btn:hover {
|
|
color: var(--interactive-accent);
|
|
border-color: var(--interactive-accent);
|
|
}
|
|
|
|
/* Popover anchored under the Import / Export buttons. */
|
|
.cd-chrome-popover {
|
|
position: absolute;
|
|
z-index: 1002;
|
|
background: var(--background-primary);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 6px;
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.25);
|
|
padding: 8px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
font-size: var(--font-ui-smaller);
|
|
width: min(420px, 70vw);
|
|
}
|
|
|
|
.cd-popover-title {
|
|
font-weight: 600;
|
|
}
|
|
|
|
.cd-chrome-popover select {
|
|
align-self: flex-start;
|
|
}
|
|
|
|
.cd-popover-textarea {
|
|
width: 100%;
|
|
min-height: 120px;
|
|
resize: vertical;
|
|
font-family: var(--font-monospace);
|
|
font-size: var(--font-smaller);
|
|
background: var(--background-secondary);
|
|
color: var(--text-normal);
|
|
border: 1px solid var(--background-modifier-border);
|
|
border-radius: 4px;
|
|
padding: 6px;
|
|
}
|
|
|
|
.cd-popover-textarea:disabled {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.cd-popover-status {
|
|
color: var(--text-muted);
|
|
min-height: 1.2em;
|
|
}
|
|
|
|
.cd-popover-action {
|
|
align-self: flex-start;
|
|
padding: 3px 10px;
|
|
border-radius: 4px;
|
|
background: var(--interactive-accent);
|
|
color: var(--text-on-accent);
|
|
border: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.cd-popover-action:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* Live draft preview, rendered with the same renderer as display mode (§7). */
|
|
.cd-editor-preview-wrap {
|
|
border-top: 1px solid var(--background-modifier-border);
|
|
padding-top: 8px;
|
|
margin-top: 4px;
|
|
overflow: auto;
|
|
max-width: 100%;
|
|
}
|
|
|
|
.cd-editor-preview {
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
.cd-editor-preview .cd-diagram-svg {
|
|
max-width: 100%;
|
|
height: auto;
|
|
}
|
|
|
|
/* Grid add-row / add-col buttons live in implicit grid tracks past the cells
|
|
(+row below, +col to the right). Their grid positions are set inline in JS.
|
|
Hidden by default and revealed only when the pointer is near the
|
|
corresponding edge (toggled via .cd-add-show-row / .cd-add-show-col from a
|
|
mousemove handler), so the editing surface stays uncluttered. */
|
|
.cd-add-row,
|
|
.cd-add-col {
|
|
font-size: 0.75em;
|
|
min-height: 22px;
|
|
padding: 0 8px;
|
|
align-self: center;
|
|
justify-self: center;
|
|
width: max-content;
|
|
opacity: 0;
|
|
transition: opacity 0.12s ease;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.cd-editor-grid.cd-add-show-row .cd-add-row,
|
|
.cd-editor-grid.cd-add-show-col .cd-add-col {
|
|
opacity: 1;
|
|
pointer-events: auto;
|
|
}
|
|
|
|
/* Per-row / per-col remove buttons reuse .cd-remove-btn (already styled) —
|
|
give the row/col variants a fixed position on the cell's outer edge. */
|
|
.cd-row-remove {
|
|
left: -10px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
right: auto;
|
|
}
|
|
|
|
.cd-col-remove {
|
|
top: -10px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
}
|
|
|
|
/* --- Phase 3: Live Preview display widget (§8.2) --- */
|
|
|
|
/* The widget replaces a ```cd block in Live Preview. Match the Reading-view
|
|
wrapper's centering so a diagram reads identically in both modes. */
|
|
.cd-lp-wrap {
|
|
margin: 0.25em 0;
|
|
text-align: center;
|
|
}
|
|
|
|
.cd-lp-wrap .cd-diagram-svg {
|
|
margin: 0 auto;
|
|
}
|
|
|
|
/* Tiny placeholder shown while MathJax typesets the diagram (one frame). */
|
|
.cd-lp-placeholder {
|
|
display: inline-block;
|
|
min-height: 1em;
|
|
color: var(--text-muted);
|
|
opacity: 0.5;
|
|
letter-spacing: 2px;
|
|
}
|
|
|
|
/* --- Phase 4: hover-to-edit affordance (§8.3) --- */
|
|
|
|
/* Wrapper around a rendered diagram in either Reading view or Live Preview when
|
|
clickToEdit is OFF. The Edit button overlays the diagram and only shows on
|
|
hover/focus, so a reader scrolling the note can't open the editor by
|
|
accident. */
|
|
.cd-diagram-wrap.cd-hover-edit,
|
|
.cd-lp-wrap.cd-hover-edit {
|
|
position: relative;
|
|
}
|
|
|
|
.cd-diagram-wrap.cd-hover-edit .cd-diagram-svg,
|
|
.cd-lp-wrap.cd-hover-edit .cd-diagram-svg {
|
|
/* The SVG is non-interactive in hover mode; the button is the click target. */
|
|
cursor: default;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* clickToEdit === true: the whole SVG opens the editor on click. The base
|
|
.cd-diagram-svg already sets cursor: pointer, but state it explicitly here so
|
|
the intent is obvious and survives a future base-style change. */
|
|
.cd-diagram-wrap.cd-click-edit .cd-diagram-svg,
|
|
.cd-lp-wrap.cd-click-edit .cd-diagram-svg {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.cd-edit-btn {
|
|
position: absolute;
|
|
top: 4px;
|
|
right: 4px;
|
|
display: none;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 2px 8px;
|
|
font-size: var(--font-ui-smaller);
|
|
color: var(--text-on-accent);
|
|
background: var(--interactive-accent);
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
opacity: 0.92;
|
|
z-index: 2;
|
|
}
|
|
|
|
.cd-hover-edit:hover .cd-edit-btn,
|
|
.cd-edit-btn:focus-visible {
|
|
display: inline-flex;
|
|
}
|
|
|
|
.cd-edit-btn:hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* --- Phase 4: grid editor keyboard focus (§7.3 a11y) --- */
|
|
|
|
/* Visible focus ring on a focused (non-editing) cell, distinct from the
|
|
editing state's accent fill so keyboard users can tell which cell is
|
|
focused vs. which is being typed in. */
|
|
.cd-cell:focus-visible {
|
|
outline: 2px solid var(--interactive-accent);
|
|
outline-offset: -2px;
|
|
}
|
|
|
|
/* Cells that hold the roving tabindex anchor (tabindex=0) get a subtle ring
|
|
even without :focus-visible, so the focused cell is discoverable after a
|
|
pointer-free interaction. */
|
|
.cd-cell[tabindex="0"]:not(.is-focused) {
|
|
box-shadow: 0 0 0 1px var(--interactive-accent-hover);
|
|
}
|
|
|
|
/* --- Improvements: resize handles, disabled chrome buttons --- */
|
|
|
|
/* Resize handles on the editor overlay (improvement #2). Eight handles: four
|
|
edges + four corners, positioned around the overlay's box. They're invisible
|
|
until hovered/focused so they don't clutter the surface, but the corner handles
|
|
sit a touch larger so they're easy to grab. pointer-events:none on the handles
|
|
themselves would defeat the purpose — they stay hit-testable. */
|
|
.cd-resize-handle {
|
|
position: absolute;
|
|
z-index: 1001;
|
|
background: transparent;
|
|
pointer-events: auto;
|
|
}
|
|
|
|
.cd-resize-n { top: -4px; left: 8px; right: 8px; height: 8px; }
|
|
.cd-resize-s { bottom: -4px; left: 8px; right: 8px; height: 8px; }
|
|
.cd-resize-e { right: -4px; top: 8px; bottom: 8px; width: 8px; }
|
|
.cd-resize-w { left: -4px; top: 8px; bottom: 8px; width: 8px; }
|
|
|
|
.cd-resize-ne { top: -4px; right: -4px; width: 14px; height: 14px; }
|
|
.cd-resize-nw { top: -4px; left: -4px; width: 14px; height: 14px; }
|
|
.cd-resize-se { bottom: -4px; right: -4px; width: 14px; height: 14px; }
|
|
.cd-resize-sw { bottom: -4px; left: -4px; width: 14px; height: 14px; }
|
|
|
|
/* A faint guide line on the resizeable edges while hovered, so the affordance
|
|
is discoverable. Corner handles get a small dot. */
|
|
.cd-resize-handle:hover {
|
|
background: var(--interactive-accent);
|
|
opacity: 0.35;
|
|
}
|
|
|
|
.cd-resize-ne:hover,
|
|
.cd-resize-nw:hover,
|
|
.cd-resize-se:hover,
|
|
.cd-resize-sw:hover {
|
|
border-radius: 50%;
|
|
opacity: 0.6;
|
|
}
|
|
|
|
/* Disabled chrome buttons (Undo/Redo when their stack is empty). */
|
|
.cd-editor-chrome-btn:disabled {
|
|
opacity: 0.4;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.cd-editor-chrome-btn:disabled:hover {
|
|
color: var(--text-normal);
|
|
border-color: var(--background-modifier-border);
|
|
}
|
|
|
|
/* Icon-only chrome button (the mode toggle, feature #1): square, centered
|
|
glyph, same border weight as the text buttons so the row stays uniform. */
|
|
.cd-editor-icon-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: auto;
|
|
min-width: 0;
|
|
padding: 2px 5px;
|
|
line-height: 0;
|
|
}
|
|
|
|
.cd-editor-icon-btn svg {
|
|
display: block;
|
|
}
|
|
|
|
/* The static diagram SVG + edit button, stashed while the embedded editor is
|
|
mounted in their place (feature #1). Collapsed with display:none (not
|
|
visibility:hidden) so they take no layout space — the in-flow editor fills the
|
|
wrapper flush, with no gap where the static diagram was. */
|
|
.cd-embedded-hidden {
|
|
display: none !important;
|
|
}
|
|
|