Files
avcf/style.css
T
adrien 8522ece371 test: C compilation tests for generated template code
- Add gcc and mesa to shell.nix for C compilation
- Fix warning icon overlap with ::after message by adding padding-right
  to proccall-header and end-header when warnings are active
- Add tests/compile/ with Makefile (pkg-config based) and run.js
  which generates C source from block-like data structures, then
  compiles with gcc -Wall -Wextra -fsyntax-only
- Tests cover: console template, simple error, error merge,
  sequential errors, value-return error style
2026-06-23 01:01:03 +02:00

1345 lines
48 KiB
CSS

:root {
--grid-size: 25px;
--bg: #fff;
--surface: #f5f5f5;
--text: #333;
--muted: #999;
--border: #ccc;
--accent: #4a90d9;
}
*, *::before, *::after { box-sizing: border-box; }
html, body {
margin: 0; padding: 0; height: 100%;
background: var(--bg); color: var(--text);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 14px; line-height: 1.4;
}
body { display: flex; flex-direction: column; }
h1 {
font-size: 1rem; padding: 0.5rem 1rem; margin: 0;
background: var(--surface); border-bottom: 1px solid var(--border); font-weight: 600;
}
.tab-bar {
display: flex; border-bottom: 1px solid var(--border);
background: var(--surface); flex-shrink: 0;
}
.tab-btn {
display: flex; align-items: center; gap: 0.35rem;
padding: 0.5rem 1rem; border: none; background: transparent;
cursor: pointer; font: inherit; font-size: 0.9rem;
border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--muted);
}
.tab-btn:hover { background: #e8e8e8; color: var(--text); }
.tab-btn.active { background: #e0e0e0; border-bottom-color: var(--accent); color: var(--text); }
.tab-icon { display: block; }
.tab-body { flex: 1; position: relative; min-height: 0; }
.tab-pane { display: none; height: 100%; flex-direction: column; }
.tab-pane.active { display: flex; }
.pane-toolbar {
display: flex; gap: 0.25rem; padding: 0.3rem;
flex-shrink: 0; flex-wrap: wrap;
background: var(--surface); border-bottom: 1px solid var(--border);
}
.pane-toolbar button {
padding: 0.3rem; font: inherit; font-size: 0.75rem; cursor: pointer;
background: var(--bg); color: var(--text); border: 1px solid var(--border);
border-radius: 3px; display: inline-flex; align-items: center; justify-content: center;
line-height: 0;
}
.pane-toolbar button:hover { background: #e8e8e8; }
.pane-toolbar button svg,
.pane-toolbar button img { display: block; }
.btn-group { position: relative; display: inline-flex; }
.submenu {
display: none; position: absolute; top: 100%; left: 0; z-index: 100;
margin-top: 2px; background: var(--bg); border: 1px solid var(--border);
border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.12);
min-width: 100px; overflow: hidden;
}
.submenu.open { display: block; }
.submenu button {
display: block; width: 100%; padding: 0.35rem 0.75rem; border: none;
border-radius: 0; text-align: left; font-size: 0.8rem; line-height: 1.4;
}
.submenu button:hover { background: #e8e8e8; }
.submenu button:not(:last-child) { border-bottom: 1px solid var(--border); }
/* ── Library sub-tab system ── */
.lib-tab-bar {
display: flex; border-bottom: 1px solid var(--border);
background: var(--surface); flex-shrink: 0;
}
.lib-tab {
padding: 0.3rem 0.7rem; border: none; background: transparent;
cursor: pointer; font: inherit; font-size: 0.8rem;
border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--muted);
}
.lib-tab:hover { background: #e8e8e8; color: var(--text); }
.lib-tab.active { background: #e0e0e0; border-bottom-color: var(--accent); color: var(--text); }
.lib-pane { display: none; flex: 1; flex-direction: column; min-height: 0; }
.lib-pane.active { display: flex; }
/* ── WCProcedure ── */
wc-procedure { gap: 0.35rem; min-width: 200px; }
wc-procedure .proc-header {
display: flex; flex-direction: column; align-items: flex-start; gap: 0.1rem; width: 100%;
}
wc-procedure .proc-natural-name {
font-weight: bold; font-size: 0.85rem;
border: none; background: transparent;
width: 100%; padding: 0.1rem; cursor: pointer;
}
wc-procedure .proc-natural-name:focus {
border: 1px solid var(--border); background: var(--bg); cursor: text;
outline: none;
}
wc-procedure .proc-tech-name {
font-size: 0.65rem; color: var(--muted);
font-family: 'Courier New', monospace;
padding: 0 0.3rem; line-height: 1.2;
}
wc-procedure .proc-params {
display: flex; gap: 0.5rem; width: 100%;
}
wc-procedure .proc-params-col {
flex: 1; display: flex; flex-direction: column; gap: 0.2rem;
}
wc-procedure .proc-params-heading {
font-size: 0.65rem; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em;
}
wc-procedure .proc-param-row {
display: flex; align-items: center; gap: 0.2rem;
}
wc-procedure .proc-param-row input {
flex: 1; background: var(--bg); border: 1px solid var(--border);
font: inherit; font-size: 0.7rem; padding: 0.1rem 0.2rem; text-align: center;
min-width: 0;
}
wc-procedure .proc-param-name { width: 4em; }
wc-procedure .proc-param-type { width: 5em; }
wc-procedure .proc-param-del {
width: 16px; height: 16px; border-radius: 50%;
border: 1px solid #ccc; background: #fff; color: #999;
font-size: 11px; line-height: 1; cursor: pointer; padding: 0;
display: flex; align-items: center; justify-content: center;
}
wc-procedure .proc-param-del:hover { background: #d32f2f; color: #fff; border-color: #d32f2f; }
wc-procedure .proc-add-input, wc-procedure .proc-add-output {
font-size: 0.7rem; padding: 0.15rem 0.4rem; cursor: pointer;
background: var(--bg); border: 1px dashed var(--border);
border-radius: 3px; color: var(--muted);
}
wc-procedure .proc-add-input:hover, wc-procedure .proc-add-output:hover {
background: #e8e8e8; color: var(--text);
}
.proc-arrow {
font-size: 1.6rem;
font-weight: bold;
color: var(--muted);
line-height: 1;
display: flex;
align-items: center;
align-self: center;
padding: 0 0.15rem;
flex-shrink: 0;
}
/* Return style selector */
wc-procedure .proc-return-row {
display: flex;
align-items: center;
gap: 0.3rem;
width: 100%;
}
wc-procedure .proc-return-label {
font-size: 0.65rem;
font-weight: 600;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.04em;
white-space: nowrap;
}
wc-procedure .proc-return-style {
font-size: 0.7rem;
padding: 0.1rem 0.3rem;
background: var(--bg);
border: 1px solid var(--border);
border-radius: 3px;
color: var(--text);
cursor: pointer;
flex: 1;
}
wc-procedure .proc-return-style:focus {
outline: none;
border-color: var(--accent, #1976d2);
}
wc-procedure[data-readonly] .proc-return-style {
display: none;
}
/* Collapsible description */
wc-procedure .proc-description {
width: 100%;
font-size: 0.72rem;
color: var(--muted);
margin-top: 0.15rem;
}
wc-procedure .proc-desc-summary {
cursor: pointer;
font-size: 0.65rem;
font-weight: 600;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 0.1rem 0;
user-select: none;
}
wc-procedure .proc-desc-summary:hover {
color: var(--text);
}
wc-procedure .proc-desc-body {
padding: 0.3rem 0.5rem;
line-height: 1.5;
color: var(--text);
font-size: 0.72rem;
background: var(--surface);
border-radius: 3px;
margin-top: 0.15rem;
}
/* List-view: two-column procedure row with arrow */
.procedures-area > wc-procedure {
gap: 0.3rem;
flex-wrap: wrap;
}
.procedures-area > wc-procedure .proc-header {
width: auto;
flex-shrink: 0;
}
.procedures-area > wc-procedure .proc-params {
width: auto;
flex: 1;
display: flex;
align-items: center;
gap: 0;
}
.procedures-area > wc-procedure .proc-params-col {
flex: none;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
gap: 0.15rem;
}
.procedures-area > wc-procedure .proc-params-col:first-of-type {
margin-right: 0.5rem;
}
.procedures-area > wc-procedure .proc-params-heading {
white-space: nowrap;
margin-right: 0.15rem;
}
.procedures-area > wc-procedure .proc-param-row input {
width: 4em;
}
.procedures-area > wc-procedure .proc-add-input,
.procedures-area > wc-procedure .proc-add-output {
white-space: nowrap;
font-size: 0.65rem;
padding: 0.1rem 0.3rem;
}
/* Read-only (external library) procedure styles */
wc-procedure[data-readonly] .proc-param-row input {
background: transparent;
border: none;
cursor: default;
color: var(--text);
font-weight: 600;
}
wc-procedure[data-readonly] .proc-param-row input:focus {
outline: none;
}
wc-procedure[data-readonly] .proc-add-input,
wc-procedure[data-readonly] .proc-add-output,
wc-procedure[data-readonly] .proc-param-del {
display: none;
}
wc-procedure[data-readonly] .proc-natural-name:focus {
outline: none;
}
wc-procedure[data-readonly] .proc-tech-name {
color: var(--text);
font-weight: 600;
}
/* ── WCProcCall ── */
wc-proccall { position: relative; gap: 0.25rem; min-width: 160px; padding-top: 1.2rem; padding-bottom: 1.2rem; }
wc-proccall .proccall-header { display: flex; align-items: center; gap: 0.25rem; width: 100%; }
wc-proccall .proccall-icon {
width: 16px; height: 16px; flex-shrink: 0; object-fit: contain;
border-radius: 2px;
}
wc-proccall .proccall-label {
font-weight: 600; font-size: 0.55rem; color: var(--muted); letter-spacing: 0.06em;
flex-shrink: 0; opacity: 0.7; text-transform: uppercase;
}
wc-proccall .proccall-nat-name {
flex: 1; font-size: 0.85rem; font-weight: 700; cursor: pointer;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
color: var(--text); line-height: 1.3;
}
wc-proccall .proccall-nat-name:hover { color: var(--accent); }
wc-proccall .proccall-tech-name {
font-size: 0.6rem; color: var(--muted); white-space: nowrap;
overflow: hidden; text-overflow: ellipsis; max-width: 100px; flex-shrink: 0;
font-family: monospace; opacity: 0.75;
}
wc-proccall .proccall-change-btn {
font-size: 0.55rem; padding: 0.08rem 0.25rem; cursor: pointer;
background: transparent; border: 1px solid var(--border); border-radius: 3px;
color: var(--muted); flex-shrink: 0; line-height: 1.3; opacity: 0.6;
}
wc-proccall .proccall-change-btn:hover { background: #e8e8e8; color: var(--text); opacity: 1; }
wc-proccall .proccall-name-row {
display: flex; align-items: center; gap: 0.25rem; width: 100%;
}
wc-proccall .proccall-name {
flex: 1; background: var(--bg); border: 1px solid var(--border);
font: inherit; font-size: 0.7rem; padding: 0.1rem 0.2rem; text-align: center;
}
wc-proccall .proccall-container {
display: flex; gap: 0.5rem; width: 100%;
}
wc-proccall .proccall-inputs, wc-proccall .proccall-outputs {
flex: 1; display: flex; flex-direction: column; gap: 0.25rem;
}
wc-proccall .proccall-arg-row {
display: flex; align-items: center; gap: 0.2rem;
}
wc-proccall .proccall-arg-label {
font-size: 0.65rem; color: var(--text); white-space: nowrap;
}
wc-proccall .proccall-arg-input {
flex: 1; background: var(--bg); border: 1px solid var(--border);
font: inherit; font-size: 0.65rem; padding: 0.1rem 0.2rem; text-align: center;
min-width: 3em;
}
/* Data hooks inside proccall arg rows are inline (position: static by default in .hook) */
wc-proccall .proccall-arg-row .hook {
position: static !important;
transform: none !important;
flex-shrink: 0;
}
/* Error hook on proccall — styled like a logic out hook but with red accent */
wc-proccall .proccall-error-hook {
background: #E69F00;
border: 2px solid #B8860B;
color: #1a1a1a;
font-size: 0.75rem;
font-weight: 900;
line-height: 1;
display: none;
}
wc-proccall button.proccall-error-hook[data-direction="out"] {
position: absolute;
right: -11px;
top: 50%;
left: auto;
bottom: auto;
z-index: 5;
width: 18px;
height: 18px;
transform: translateY(-50%);
}
wc-proccall button.proccall-error-hook:hover {
transform: translateY(-50%) scale(1.3);
box-shadow: 0 0 6px rgba(230,159,0,0.6);
}
wc-proccall button.proccall-error-hook.visible {
display: inline-flex;
align-items: center;
justify-content: center;
}
wc-proccall .proccall-fmtargs {
display: flex; flex-direction: column; gap: 0.15rem; width: 100%;
border-top: 1px dashed var(--border); padding-top: 0.2rem; margin-top: 0.1rem;
}
wc-proccall .proccall-fmtargs-list {
display: flex; flex-direction: column; gap: 0.15rem;
}
wc-proccall .proccall-add-fmtarg {
font-size: 0.6rem; padding: 0.1rem 0.3rem; cursor: pointer;
background: transparent; border: 1px dashed var(--border); border-radius: 3px;
color: var(--muted); align-self: flex-start;
}
wc-proccall .proccall-add-fmtarg:hover { background: #e8e8e8; color: var(--text); }
wc-proccall .proccall-fmtargs .proccall-arg-row .hook {
position: static !important;
transform: none !important;
flex-shrink: 0;
}
/* ── WCAssign ── */
wc-assign { gap: 0.25rem; padding-top: 1.2rem; padding-bottom: 1.2rem; }
wc-assign .assign-header { font-weight: bold; font-size: 0.65rem; color: var(--muted); letter-spacing: 0.05em; }
wc-assign .assign-row { display: flex; align-items: center; gap: 0.25rem; width: 100%; }
wc-assign .assign-target {
flex: 1; background: var(--bg); border: 1px solid var(--border);
font: inherit; font-size: 0.75rem; padding: 0.1rem 0.2rem;
}
wc-assign .assign-eq { font-size: 0.8rem; font-weight: bold; color: var(--text); }
wc-assign .assign-value {
flex: 1; background: var(--bg); border: 1px solid var(--border);
font: inherit; font-size: 0.75rem; padding: 0.15rem 0.3rem; text-align: center;
min-width: 4em;
}
wc-assign .assign-value.hidden { display: none; }
wc-assign .assign-index-area {
display: none; align-items: center; gap: 0.2rem; width: 100%;
justify-content: flex-end;
}
wc-assign .assign-index-area .hook {
position: static !important;
transform: none !important;
flex-shrink: 0;
}
wc-assign .assign-bracket { font-size: 0.85rem; font-weight: bold; color: var(--muted); }
wc-assign .assign-index {
width: 3em; background: var(--bg); border: 1px solid var(--border);
font: inherit; font-size: 0.75rem; padding: 0.15rem 0.3rem; text-align: center;
}
wc-assign .assign-index.hidden { display: none; }
wc-assign .assign-row .hook {
position: static !important;
transform: none !important;
flex-shrink: 0;
}
wc-assign #hook-fore[data-direction="in"] {
left: -7px; top: 50%; transform: translateY(-50%); bottom: auto;
}
wc-assign #hook-next[data-direction="out"] {
right: -7px; top: 50%; transform: translateY(-50%); bottom: auto; left: auto;
}
#draw-area {
flex: 1; position: relative; min-height: 0;
overflow: auto;
background-size: var(--grid-size) var(--grid-size);
background-image:
linear-gradient(to right, #eee 1px, transparent 1px),
linear-gradient(to bottom, #eee 1px, transparent 1px);
background-color: var(--bg);
}
/* Column headers for list-style containers */
.list-header {
display: flex;
align-items: center;
gap: 0.35rem;
padding: 0.3rem 0.5rem;
font-size: 0.6rem;
font-weight: 700;
color: var(--muted);
text-transform: uppercase;
letter-spacing: 0.06em;
background: var(--surface);
border-bottom: 2px solid var(--border);
flex-shrink: 0;
white-space: nowrap;
overflow: hidden;
min-height: 1.8em;
}
/* List-style containers for non-algorithm tabs */
#data-area, #variable-area, .procedures-area {
flex: 1; min-height: 0;
overflow: auto;
background: var(--bg);
display: flex;
flex-direction: column;
}
.global-toolbar {
display: flex; gap: 0.25rem; padding: 0.3rem;
align-items: flex-start; flex-shrink: 0;
border-top: 1px solid var(--border); background: var(--surface);
}
.global-toolbar button {
padding: 0.4rem 0.8rem; font: inherit; font-size: 0.8rem; cursor: pointer;
background: var(--accent); color: #fff; border: none; border-radius: 3px;
}
.global-toolbar button:hover { background: #357abd; }
.global-toolbar .code-output {
flex: 1; min-height: 80px; max-height: 50vh; overflow: auto; resize: vertical;
background: var(--bg); border: 1px solid var(--border);
font-family: 'Courier New', monospace; font-size: 0.8rem; line-height: 1.5;
padding: 0.3rem; position: relative;
}
.global-toolbar .code-output pre {
margin: 0; white-space: pre; tab-size: 4;
}
.global-toolbar .code-output code {
display: block;
}
.global-toolbar .code-output code.hljs {
background: transparent; padding: 0;
}
[data-block] {
border: 1px solid var(--border); padding: 0.5rem; margin: 0;
position: absolute; display: flex; justify-content: center;
align-items: center; flex-direction: column; user-select: none;
background: var(--bg); color: var(--text); min-width: 60px; min-height: 30px;
overflow: visible; border-radius: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); z-index: 1;
}
/* Algorithm-tab blocks — wider minimum to avoid hook/button overlap */
#main-program > [data-block] {
min-width: 100px;
}
/* List-view blocks (non-algorithm tabs) — horizontal rows, no positioning */
#variable-area > [data-block],
#data-area > [data-block],
.procedures-area > [data-block] {
position: static;
width: 100%;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
gap: 0.35rem;
padding: 0.35rem 0.5rem;
min-width: auto;
min-height: auto;
box-shadow: none;
border-radius: 0;
border-left: none;
border-right: none;
border-top: none;
border-bottom: 1px solid var(--border);
margin: 0;
z-index: auto;
}
/* Flatten internal row wrappers in list-view blocks */
#variable-area > [data-block] .datum-row,
#data-area > [data-block] .datum-row {
display: contents;
}
/* Hide resize handle in list view */
#variable-area > [data-block] .resize-handle,
#data-area > [data-block] .resize-handle,
.procedures-area > [data-block] .resize-handle {
display: none;
}
/* Inline delete button for list-view blocks */
#variable-area > [data-block] .delete-btn,
#data-area > [data-block] .delete-btn,
.procedures-area > [data-block] .delete-btn {
position: static;
opacity: 0.4;
margin-left: auto;
flex-shrink: 0;
}
[data-block]:hover .resize-handle { opacity: 0.5; }
.resize-handle {
position: absolute; right: 0; bottom: 0; width: 14px; height: 14px;
cursor: nwse-resize; opacity: 0; z-index: 10;
background: linear-gradient(135deg, transparent 50%, var(--muted) 50%, var(--muted) 60%, transparent 60%);
transition: opacity 0.15s;
}
wc-start { background: #e8f5e9; border-color: #66bb6a; }
wc-end { background: #fbe9e7; border-color: #ef5350; }
wc-end[data-exit-error="true"] {
background: #fff5f5;
border-color: #ef5350;
}
wc-end[data-exit-error="true"] .end-header::after {
content: " (error)";
font-weight: normal;
font-size: 0.65rem;
color: #e57373;
}
wc-end .end-header { font-weight: bold; font-size: 0.75rem; letter-spacing: 0.05em; }
wc-end .end-exit-row {
display: flex; align-items: center; gap: 0.3rem; width: 100%;
}
wc-end .end-exit-label {
font-size: 0.65rem; font-weight: 600; color: var(--muted);
text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap;
}
wc-end .end-exit-autocomplete {
position: relative; flex: 1; min-width: 0;
}
wc-end .end-errno-input {
width: 100%; font-size: 0.7rem; padding: 0.1rem 0.25rem;
background: var(--bg); border: 1px solid var(--border);
border-radius: 3px; color: var(--text);
font-family: 'Courier New', monospace; outline: none;
}
wc-end .end-errno-input:focus {
border-color: var(--accent);
}
wc-end .end-errno-suggestions {
display: none; position: absolute; top: 100%; left: 0; right: 0;
z-index: 100; background: var(--bg); border: 1px solid var(--border);
border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.12);
max-height: 180px; overflow-y: auto;
}
wc-end .end-errno-suggestion {
padding: 0.2rem 0.4rem; cursor: pointer;
border-bottom: 1px solid var(--border);
}
wc-end .end-errno-suggestion:last-child { border-bottom: none; }
wc-end .end-errno-suggestion:hover,
wc-end .end-errno-suggestion.highlighted { background: #e8f0fe; }
wc-end .end-suggestion-code {
display: block; font-size: 0.7rem;
font-family: 'Courier New', monospace;
}
wc-end .end-suggestion-desc {
display: block; font-size: 0.6rem; color: var(--muted); font-style: italic;
}
wc-end .end-desc-row {
display: flex; align-items: center; width: 100%;
padding: 0 0.3rem; min-height: 1.3em;
}
wc-end .end-desc-text {
font-size: 0.65rem; color: var(--muted); font-style: italic;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
wc-decision { background: #fff3e0; border-color: #ffa726; }
wc-decision p { margin: 0.2rem 0; font-weight: 600; }
wc-decision .decision-row { display: flex; align-items: center; gap: 0.3rem; }
wc-decision .decision-label { font-size: 0.8rem; font-weight: bold; color: var(--text); }
/* ── Unified warning system ──────────────────────────────────────────── */
/* The ⚠ icon (block-warn) is created for every algorithm block.
It stays hidden until any warning class is active on the block. */
.block-warn { display: none; font-size: 1rem; cursor: help; position: absolute; top: 2px; right: 4px; z-index: 3; }
/* Warning: block has no incoming logic connection */
#main-program > [data-block].disconnected { border-color: #e65100; border-width: 2px; background: #fff3e0; }
#main-program > [data-block].disconnected > .block-warn { display: inline; color: #e65100; }
/* Warning: error output hook on wc-proccall is not connected */
wc-proccall.warn-error-unlinked {
box-shadow: 0 0 0 2px #ef5350, 0 1px 3px rgba(0,0,0,0.08);
}
wc-proccall.warn-error-unlinked > .block-warn { display: inline; color: #ef5350; }
wc-proccall.warn-error-unlinked .proccall-header {
padding-right: 1.2rem;
}
wc-proccall.warn-error-unlinked .proccall-header::after {
content: " (unused)"; font-size: 0.65rem; color: #ef5350; font-weight: normal;
}
/* Warning: error-path END block returns 0 (success) */
wc-end.warn-zero-in-error {
border-color: #ffa000;
border-width: 2px;
background: #fff8e1;
}
wc-end.warn-zero-in-error > .block-warn { display: inline; color: #ffa000; }
wc-end.warn-zero-in-error .end-header {
padding-right: 1.8rem;
}
wc-end.warn-zero-in-error .end-header::after {
content: " (success in error path)";
font-size: 0.6rem; color: #ffa000; font-weight: normal;
}
wc-decision .decision-row .hook {
position: static !important;
transform: none !important;
flex-shrink: 0;
}
wc-boolean, wc-scalar, wc-vector, wc-string { gap: 0.25rem; }
wc-boolean .datum-row, wc-scalar .datum-row, wc-vector .datum-row, wc-string .datum-row { display: flex; align-items: center; gap: 0.25rem; width: 100%; }
wc-boolean input, wc-scalar input, wc-vector input, wc-string input {
background: var(--bg); border: 1px solid var(--border); font: inherit;
padding: 0.15rem 0.3rem; width: 4em; text-align: center;
}
wc-boolean .var-name, wc-scalar .var-name, wc-vector .var-name, wc-string .var-name, wc-array .var-name {
border: none; background: transparent; cursor: pointer;
font-weight: bold; font-size: 0.85rem;
width: auto; min-width: 2em; padding: 0.1rem;
}
wc-boolean .var-name:focus, wc-scalar .var-name:focus, wc-vector .var-name:focus, wc-string .var-name:focus, wc-array .var-name:focus {
border: 1px solid var(--border); background: var(--bg); cursor: text;
outline: none; width: 5em;
}
wc-boolean .var-comment, wc-scalar .var-comment, wc-vector .var-comment, wc-string .var-comment, wc-array .var-comment {
border: none; background: transparent;
font-style: italic; font-size: 0.7rem; color: var(--muted);
width: 100%; padding: 0.1rem 0.3rem; cursor: pointer;
text-align: left;
}
wc-boolean .var-comment:focus, wc-scalar .var-comment:focus, wc-vector .var-comment:focus, wc-string .var-comment:focus, wc-array .var-comment:focus {
border: 1px solid var(--border); background: var(--bg);
font-style: italic; color: var(--text); cursor: text;
outline: none;
}
wc-boolean .var-cname, wc-scalar .var-cname, wc-vector .var-cname, wc-string .var-cname, wc-array .var-cname {
font-size: 0.65rem; color: var(--muted); font-family: 'Courier New', monospace;
width: 100%; padding: 0 0.3rem; line-height: 1.2;
}
wc-boolean .var-value, wc-scalar .var-value, wc-vector .var-value { width: 8em; }
wc-string .var-value { width: 8em; }
wc-array { gap: 0.25rem; background: #e0f2f1; border-color: #26a69a; }
wc-array .array-row { display: flex; align-items: center; gap: 0.25rem; width: 100%; }
/* In list view, array elements span full width below the row */
#variable-area > wc-array .array-elements {
width: 100%; order: 999; flex-shrink: 0;
}
wc-array .array-type { width: 7em; }
wc-array .array-bracket { font-size: 0.85rem; font-weight: bold; }
wc-array .array-count { font-size: 0.7rem; color: var(--muted); margin-left: auto; white-space: nowrap; }
wc-array .array-elements {
display: flex; flex-direction: column; gap: 0.15rem; width: 100%;
overflow: visible;
}
wc-array .array-element-row {
display: flex; align-items: center; gap: 0.25rem;
}
wc-array .array-element-idx {
font-size: 0.7rem; color: var(--muted); width: 1.5em; text-align: right; flex-shrink: 0;
font-family: 'Courier New', monospace;
}
wc-array .array-element-value {
flex: 1; background: var(--bg); border: 1px solid var(--border);
font: inherit; font-size: 0.75rem; padding: 0.1rem 0.3rem; text-align: center;
min-width: 3em;
}
wc-array .array-element-del {
width: 16px; height: 16px; border-radius: 50%; flex-shrink: 0;
border: 1px solid #ccc; background: #fff; color: #999;
font-size: 11px; line-height: 1; cursor: pointer; padding: 0;
display: flex; align-items: center; justify-content: center;
}
wc-array .array-element-del:hover { background: #d32f2f; color: #fff; border-color: #d32f2f; }
wc-array .array-vec-row { font-size: 0.7rem; color: var(--muted); white-space: nowrap; margin-left: auto; }
wc-array .array-vec-dim { width: 2.5em; text-align: center; font: inherit; font-size: 0.75rem; background: var(--bg); border: 1px solid var(--border); padding: 0.1rem 0.2rem; }
wc-scalar .var-si, wc-vector .var-si { font-size: 0.75rem; color: var(--muted); white-space: nowrap; }
wc-scalar .var-type, wc-scalar .var-unit, wc-vector .var-type, wc-vector .var-unit {
background: var(--bg); border: 1px solid var(--border);
font: inherit; font-size: 0.75rem; padding: 0.1rem 0.2rem;
}
wc-vector .var-dim { width: 2.5em; text-align: center; }
wc-expression { gap: 0.25rem; }
wc-expression .expr-row { display: flex; align-items: center; gap: 0.25rem; width: 100%; }
wc-expression input {
background: var(--bg); border: 1px solid var(--border); font: inherit;
padding: 0.15rem 0.3rem; text-align: center;
}
wc-expression .expr-name { width: 3em; }
wc-expression .expr-formula-container {
display: flex; gap: 0.25rem; width: 100%;
}
wc-expression .expr-latex {
flex: 1; background: var(--bg); border: 1px solid var(--border);
font-family: 'Courier New', monospace; font-size: 0.75rem;
padding: 0.2rem; resize: vertical; min-width: 4em;
}
wc-expression .expr-rendered {
min-width: 3em; min-height: 2em; display: flex; align-items: center;
justify-content: center; background: #fafafa; border: 1px solid #eee;
border-radius: 3px; padding: 0.2rem 0.4rem; font-size: 0.8rem;
}
wc-expression .expr-varhooks {
position: absolute; top: -7px; left: 0; right: 0; z-index: 3;
display: flex; justify-content: center; gap: 6px;
pointer-events: none; height: 14px;
}
wc-expression .expr-varhooks .hook {
position: static; pointer-events: auto; flex-shrink: 0;
transform: none !important;
}
wc-varref { gap: 0.25rem; padding-bottom: 1rem; }
wc-varref .varref-label { font-weight: bold; font-size: 0.65rem; color: var(--muted); letter-spacing: 0.05em; }
wc-varref .varref-select {
background: var(--bg); border: 1px solid var(--border); font: inherit;
font-size: 0.75rem; padding: 0.15rem 0.2rem; width: 100%;
}
wc-quantity { gap: 0.25rem; }
wc-quantity .quantity-header { display: flex; align-items: center; gap: 0.3rem; width: 100%; }
wc-quantity .quantity-label { font-weight: bold; font-size: 0.7rem; }
wc-quantity .quantity-name {
flex: 1; background: var(--bg); border: 1px solid var(--border);
font: inherit; padding: 0.15rem 0.3rem; text-align: center;
}
wc-quantity .dims { display: flex; flex-wrap: wrap; gap: 0.2rem; justify-content: center; }
wc-quantity .dims label { display: flex; align-items: center; gap: 0.1rem; font-size: 0.75rem; font-weight: bold; }
wc-quantity .dims input {
width: 2.5em; background: var(--bg); border: 1px solid var(--border);
padding: 0.1rem; font: inherit; text-align: center;
}
wc-quantity .range { display: flex; gap: 0.5rem; font-size: 0.75rem; }
wc-quantity .range input {
width: 4em; background: var(--bg); border: 1px solid var(--border);
padding: 0.1rem 0.2rem; font: inherit; text-align: center;
}
wc-quantity .quantity-footer { width: 100%; font-size: 0.75rem; }
wc-quantity .quantity-footer select {
width: 100%; background: var(--bg); border: 1px solid var(--border);
font: inherit; padding: 0.1rem 0.2rem;
}
/* List-view: flatten quantity internals into a row */
#data-area > wc-quantity .quantity-header,
#data-area > wc-quantity .dims,
#data-area > wc-quantity .range,
#data-area > wc-quantity .quantity-footer {
display: contents;
}
wc-unit { gap: 0.25rem; }
wc-unit .unit-header { display: flex; align-items: center; gap: 0.3rem; width: 100%; }
wc-unit .unit-label { font-weight: bold; font-size: 0.7rem; }
wc-unit .unit-fullname {
flex: 1; background: var(--bg); border: 1px solid var(--border);
font: inherit; padding: 0.15rem 0.3rem; text-align: center;
}
wc-unit .unit-body { display: flex; flex-direction: column; gap: 0.2rem; width: 100%; }
wc-unit .unit-body label { display: flex; align-items: center; gap: 0.3rem; font-size: 0.8rem; }
wc-unit .unit-body select, wc-unit .unit-body input {
flex: 1; background: var(--bg); border: 1px solid var(--border);
font: inherit; padding: 0.1rem 0.2rem; text-align: center;
}
wc-unit .unit-si { width: 7em; }
wc-unit .unit-resolved { font-size: 0.75rem; color: var(--muted); align-self: flex-end; }
/* List-view: flatten unit internals */
#data-area > wc-unit .unit-header,
#data-area > wc-unit .unit-body {
display: contents;
}
#data-area > wc-unit .unit-body label {
display: inline-flex;
}
.error-overlay {
display: none; position: fixed; z-index: 99999;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.45);
align-items: center; justify-content: center;
}
.error-overlay.active { display: flex; }
.error-box {
background: #d32f2f; color: #fff; padding: 2rem;
border-radius: 8px; max-width: 400px; width: 90%;
box-shadow: 0 4px 24px rgba(0,0,0,0.35);
text-align: center; position: relative;
}
.error-ack {
font-size: 2.2rem; font-weight: 900;
font-family: 'Courier New', monospace;
letter-spacing: 0.1em; margin-bottom: 0.75rem;
}
.error-close {
position: absolute; top: 0.3rem; right: 0.75rem;
cursor: pointer; font-size: 1.8rem; line-height: 1;
opacity: 0.8;
}
.error-close:hover { opacity: 1; }
.error-msg { font-size: 1rem; line-height: 1.5; }
svg#connections {
z-index: 0; background: transparent; position: absolute;
top: 0; left: 0; width: 100%; height: 100%;
overflow: visible; pointer-events: none;
}
svg#connections path.flow, svg#connections path.flow-data {
pointer-events: stroke;
}
path.flow { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; transition: stroke 0.1s, stroke-width 0.1s; }
path.flow:hover { stroke: #d32f2f; stroke-width: 3; cursor: pointer; }
path.flow-shadow { fill: none; stroke: var(--accent); stroke-width: 1.5; stroke-dasharray: 5 3; pointer-events: none; opacity: 0.6; }
path.flow-data { fill: none; stroke: #43a047; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; transition: stroke 0.1s, stroke-width 0.1s; }
path.flow-data:hover { stroke: #d32f2f; stroke-width: 3; cursor: pointer; }
path.flow-shadow-data { fill: none; stroke: #43a047; stroke-width: 1.5; stroke-dasharray: 5 3; pointer-events: none; opacity: 0.6; }
/* ── Logic sections ── */
.section-bg { fill: #e8e8e8; fill-opacity: 0.5; stroke: #ccc; stroke-width: 1; stroke-dasharray: 4 2; cursor: pointer; }
.section-bg:hover { stroke: #999; stroke-width: 1.5; }
.section-bg.selected-section { stroke: #666; stroke-width: 2; stroke-dasharray: none; fill-opacity: 0.6; }
.section-label { font-size: 11px; font-family: sans-serif; fill: #888; cursor: pointer; user-select: none; pointer-events: auto; }
.section-label:hover { fill: #555; }
.section-handle { fill: #666; stroke: #fff; stroke-width: 1.5; cursor: move; }
.section-preview-bg { fill: #e0e0e0; fill-opacity: 0.4; stroke: #aaa; stroke-width: 1; stroke-dasharray: 4 3; }
.section-preview-line { stroke: #888; stroke-width: 1.5; stroke-dasharray: 4 3; }
.section-ghost { fill: #888; }
.section-title-input { font-size: 11px; border: 1px solid #aaa; border-radius: 2px; padding: 1px 4px; background: #fff; }
/* Edit-mode overlay greys out blocks/links */
.section-edit-overlay { position: absolute; inset: 0; z-index: 4; background: transparent; pointer-events: none; }
#draw-area.section-editing [data-block] { opacity: 0.3; pointer-events: none; }
#draw-area.section-editing path.flow, #draw-area.section-editing path.flow-data, #draw-area.section-editing path.flow-shadow, #draw-area.section-editing path.flow-shadow-data { opacity: 0.2; pointer-events: none; }
#draw-area.section-editing .section-bg { pointer-events: auto; fill-opacity: 0.7; }
#draw-area.section-editing .section-label { pointer-events: auto; }
#draw-area.section-editing .section-handle { pointer-events: auto; }
#draw-area.section-editing .section-preview-bg { pointer-events: none; }
#draw-area.section-editing .section-preview-line { pointer-events: none; }
#draw-area.section-editing .section-ghost { pointer-events: none; }
.toolbar-sep { display: inline-block; width: 1px; height: 18px; background: var(--border); margin: 0 4px; vertical-align: middle; }
button.hook {
display: block; width: 14px; height: 14px; border-radius: 50%;
cursor: pointer; padding: 0; z-index: 2;
transition: transform 0.1s, box-shadow 0.1s;
}
/* Hook row for bottom-placed output hooks (side by side) */
.hook-row {
display: flex; gap: 8px; justify-content: center;
position: absolute; bottom: -7px; left: 0; right: 0;
pointer-events: none;
}
.hook-row > .hook { position: static; pointer-events: auto; }
button.hook[data-direction="out"] {
background: var(--accent); border: 2px solid var(--accent);
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
position: absolute; bottom: -7px; left: 50%; transform: translateX(-50%);
}
.hook-row > button.hook[data-direction="out"] {
position: static; transform: none;
}
button.hook[data-direction="out"]:hover {
transform: translateX(-50%) scale(1.3);
box-shadow: 0 0 8px rgba(74,144,217,0.5), 0 1px 3px rgba(0,0,0,0.2);
}
.hook-row > button.hook[data-direction="out"]:hover {
transform: scale(1.3);
}
button.hook[data-direction="in"] {
background: transparent;
border: 2px dashed var(--muted);
position: absolute;
}
button.hook[data-direction="in"][data-exit="up"] {
top: -7px; left: 50%; transform: translateX(-50%);
}
button.hook[data-direction="in"][data-exit="left"] {
top: 50%; left: -7px; transform: translateY(-50%);
}
button.hook[data-direction="in"][data-exit="right"] {
top: 50%; right: -7px; transform: translateY(-50%);
}
/* Empty input hooks hidden by default; shown during linking */
button.hook[data-direction="in"]:not([data-connected]) {
display: none;
}
#draw-area.linking button.hook[data-direction="in"],
#draw-area.linking button.hook[data-direction="in"]:not([data-connected]) {
display: block;
}
button.hook[data-direction="in"]:hover {
border-color: var(--accent); border-style: solid;
}
button.hook[data-direction="in"][data-connected] {
display: block;
background: #e8f0fe;
border-color: var(--accent);
border-style: solid;
}
button.hook:not([data-direction]) {
opacity: 0.2; pointer-events: none;
}
button.hook[data-link-type="data"][data-direction="out"] {
background: #43a047; border-color: #43a047;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
button.hook[data-link-type="data"][data-direction="out"]:hover {
transform: translateX(-50%) scale(1.3);
box-shadow: 0 0 8px rgba(67,160,71,0.5), 0 1px 3px rgba(0,0,0,0.2);
}
button.hook[data-link-type="data"][data-direction="in"] {
background: transparent;
border: 2px dashed #43a047;
}
button.hook[data-link-type="data"][data-direction="in"]:hover {
border-style: solid;
}
button.hook[data-link-type="data"][data-direction="in"][data-connected] {
background: #e8f5e9;
border-color: #43a047;
border-style: solid;
}
/* Error hook on wc-proccall — red to match WCEnd border */
button.hook.proccall-error-hook,
button.hook.proccall-error-hook[data-direction="out"] {
background: #ef5350; border-color: #ef5350;
}
button.hook.proccall-error-hook[data-direction="out"]:hover {
transform: scale(1.3);
box-shadow: 0 0 8px rgba(239,83,80,0.5), 0 1px 3px rgba(0,0,0,0.2);
}
/* Error flow paths — red */
path.flow.flow-error { stroke: #ef5350; }
/* Blocks only reachable via error paths */
[data-block].error-path {
border-color: #ef5350;
background: #fff5f5;
}
wc-decision #hook-fore[data-direction="in"] {
left: -7px; top: 50%; transform: translateY(-50%); bottom: auto;
}
.selected {
box-shadow: 0 0 0 2px var(--accent), 0 1px 3px rgba(0,0,0,0.08);
}
/* Compact field display (replaces input/select inside blocks) */
#main-program > [data-block] .field-display {
font-size: 0.75rem; color: var(--text); white-space: nowrap;
overflow: hidden; text-overflow: ellipsis; max-width: 100%;
display: inline-block; line-height: 1.4;
}
.delete-btn {
position: absolute; top: -8px; right: -8px;
width: 18px; height: 18px; border-radius: 50%;
border: 1px solid #ccc; background: #fff; color: #999;
font-size: 13px; line-height: 1; cursor: pointer; padding: 0;
display: flex; align-items: center; justify-content: center;
z-index: 20; opacity: 0; transition: opacity 0.12s;
}
.delete-btn:hover {
opacity: 1 !important; background: #d32f2f; color: #fff; border-color: #d32f2f;
}
[data-block]:hover .delete-btn, .selected .delete-btn {
opacity: 0.6;
}
/* Edit (pencil) button — sits left of the delete button */
.edit-btn {
position: absolute; top: -8px; right: 14px;
width: 18px; height: 18px; border-radius: 50%;
border: 1px solid #ccc; background: #fff; color: #999;
cursor: pointer; padding: 0;
display: flex; align-items: center; justify-content: center;
z-index: 20; opacity: 0; transition: opacity 0.12s;
}
.edit-btn:hover {
opacity: 1 !important; background: var(--accent); color: #fff; border-color: var(--accent);
}
[data-block]:hover .edit-btn, .selected .edit-btn {
opacity: 0.6;
}
textarea { white-space: pre-wrap; }
select {
background: var(--bg); color: var(--text); border: 1px solid var(--border);
font: inherit; font-size: 0.75rem; padding: 0.1rem 0.2rem;
}
select option { background: var(--bg); color: var(--text); }
input { color-scheme: light; }
* { scrollbar-color: var(--border) var(--bg); scrollbar-width: thin; }
/* ── Procedure Browser Modal ── */
.proc-browser-overlay {
display: none; position: fixed; z-index: 99998;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.45);
align-items: center; justify-content: center;
}
.proc-browser-overlay.active { display: flex; }
.proc-browser-box {
background: #fff; color: #333;
border-radius: 8px; max-width: 500px; width: 90%;
max-height: 70vh; display: flex; flex-direction: column;
box-shadow: 0 4px 24px rgba(0,0,0,0.35);
}
.proc-browser-header {
padding: 0.75rem 1rem; font-weight: 600; font-size: 0.9rem;
border-bottom: 1px solid var(--border);
display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0;
}
.proc-browser-search {
flex: 1; padding: 0.3rem 0.5rem; border: 1px solid var(--border);
border-radius: 4px; font: inherit; font-size: 0.8rem;
outline: none; min-width: 0; color-scheme: light;
}
.proc-browser-search:focus { border-color: var(--accent); }
.proc-browser-tree {
flex: 1; overflow-y: auto; padding: 0.25rem 0;
min-height: 120px;
}
.proc-browser-empty {
padding: 2rem; text-align: center; color: var(--muted);
font-size: 0.85rem; display: none; line-height: 1.6;
}
.proc-browser-empty a {
color: var(--accent); text-decoration: underline; cursor: pointer;
}
/* Tree group (collapsible section for each library) */
.proc-browser-tree-group-header {
display: flex; align-items: center; gap: 0.3rem;
padding: 0.25rem 0.75rem; cursor: pointer;
user-select: none; font-size: 0.8rem;
border-top: 1px solid #eee; border-bottom: 1px solid #eee;
margin-top: -1px;
}
.proc-browser-tree-group-header:hover { background: #f5f5f5; }
.proc-browser-tree-group-header.user-defined {
font-weight: 700; border-top: 2px solid var(--accent); background: #f8faff;
}
.proc-browser-tree-arrow {
font-size: 0.55rem; color: var(--muted);
width: 0.8em; flex-shrink: 0;
}
.proc-browser-tree-group-name { font-weight: 600; }
.proc-browser-tree-group-count {
font-size: 0.65rem; color: var(--muted); margin-left: auto;
}
.proc-browser-tree-group-items { padding: 0; }
/* Tree leaf (individual procedure) */
.proc-browser-tree-leaf {
display: flex; align-items: center; gap: 0.5rem;
padding: 0.25rem 0.75rem 0.25rem 1.75rem;
cursor: pointer; font-size: 0.8rem;
border-left: 3px solid transparent;
}
.proc-browser-tree-leaf:hover { background: #f0f4ff; }
.proc-browser-tree-leaf.selected {
background: #e3f0ff; border-left-color: var(--accent); font-weight: 600;
}
.proc-browser-tree-leaf-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.proc-browser-tree-leaf-qname {
font-size: 0.65rem; color: var(--muted);
font-family: 'Courier New', monospace; flex-shrink: 0;
}
.proc-browser-footer {
display: flex; gap: 0.5rem; justify-content: flex-end;
padding: 0.75rem 1rem;
border-top: 1px solid var(--border); flex-shrink: 0;
}
.proc-browser-footer button {
padding: 0.4rem 0.8rem; font: inherit; font-size: 0.8rem;
cursor: pointer; border-radius: 3px;
}
.proc-browser-cancel {
background: var(--bg); color: var(--text);
border: 1px solid var(--border);
}
.proc-browser-cancel:hover { background: #e8e8e8; }
.proc-browser-select {
background: var(--accent); color: #fff; border: none;
}
.proc-browser-select:hover { background: #357abd; }
/* ── In-app test panel ── */
#apptest-panel {
position: fixed; top: 0; right: 0; width: 380px; max-height: 100vh;
background: #1e1e2e; color: #cdd6f4; font-family: monospace; font-size: 0.75rem;
z-index: 10000; display: flex; flex-direction: column;
border-left: 2px solid #45475a; box-shadow: -4px 0 12px rgba(0,0,0,0.4);
}
#apptest-panel .apptest-toolbar {
display: flex; align-items: center; justify-content: space-between;
padding: 0.4rem 0.6rem; background: #181825; border-bottom: 1px solid #45475a;
}
#apptest-panel .apptest-title { font-weight: bold; font-size: 0.8rem; }
#apptest-panel .apptest-close {
background: none; border: none; color: #cdd6f4; cursor: pointer;
font-size: 1rem; padding: 0 0.3rem;
}
#apptest-panel .apptest-close:hover { color: #f38ba8; }
#apptest-panel .apptest-copy {
background: none; border: 1px solid #585b70; border-radius: 0.3rem;
color: #cdd6f4; cursor: pointer; font-size: 0.7rem; padding: 0.15rem 0.5rem;
margin-left: auto; margin-right: 0.5rem;
}
#apptest-panel .apptest-copy:hover { background: #313244; }
#apptest-panel .apptest-body {
flex: 1; overflow-y: auto; padding: 0.3rem 0;
}
#apptest-panel .apptest-group {
font-weight: bold; padding: 0.4rem 0.6rem 0.15rem;
color: #89b4fa; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.05em;
}
#apptest-panel .apptest-row {
display: flex; align-items: baseline; gap: 0.3rem;
padding: 0.15rem 0.6rem 0.15rem 1.2rem; line-height: 1.5;
}
#apptest-panel .apptest-icon { flex-shrink: 0; font-weight: bold; }
#apptest-panel .apptest-pass .apptest-icon { color: #a6e3a1; }
#apptest-panel .apptest-fail .apptest-icon { color: #f38ba8; }
#apptest-panel .apptest-name { }
#apptest-panel .apptest-detail {
color: #f38ba8; font-size: 0.65rem; margin-left: auto;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#apptest-panel .apptest-summary {
padding: 0.5rem 0.6rem; font-weight: bold; text-align: center;
border-bottom: 1px solid #45475a;
}
#apptest-panel .apptest-summary.apptest-pass { color: #a6e3a1; }
#apptest-panel .apptest-summary.apptest-fail { color: #f38ba8; }
/* New Project modal */
.modal-overlay {
position: fixed; inset: 0; z-index: 100;
background: rgba(0,0,0,0.5);
display: flex; align-items: center; justify-content: center;
}
.modal {
background: var(--surface); border: 1px solid var(--border);
border-radius: 0.5rem; padding: 1.2rem 1.5rem;
min-width: 380px; max-width: 440px;
box-shadow: 0 8px 32px rgba(0,0,0,0.2);
}
.modal h2 { margin: 0 0 1rem; font-size: 1.1rem; }
.modal-field { margin-bottom: 1rem; }
.modal-field label {
display: block; font-size: 0.8rem; font-weight: 600;
margin-bottom: 0.3rem; color: var(--muted);
}
.modal-input {
width: 100%; padding: 0.4rem 0.5rem;
border: 1px solid var(--border); border-radius: 0.3rem;
font-size: 0.9rem; background: var(--bg); color: var(--text);
}
.template-list { display: flex; flex-direction: column; gap: 0.4rem; }
.template-card {
display: flex; align-items: center; gap: 0.6rem;
padding: 0.5rem 0.7rem; border: 1px solid var(--border);
border-radius: 0.3rem; cursor: pointer; user-select: none;
transition: border-color 0.15s, background 0.15s;
}
.template-card:hover { border-color: var(--accent); }
.template-card.selected {
border-color: var(--accent); background: #e8f0fe;
}
.template-card.selected .template-icon::after {
content: " \2713"; font-size: 0.85rem; color: var(--accent);
}
.template-icon { font-size: 1.3rem; flex-shrink: 0; }
.template-name { font-weight: 600; font-size: 0.85rem; }
.template-desc {
font-size: 0.7rem; color: var(--muted); margin-left: auto;
white-space: nowrap;
}
.modal-actions {
display: flex; justify-content: flex-end; gap: 0.5rem;
margin-top: 0.5rem;
}
.modal-btn {
padding: 0.4rem 1rem; border: 1px solid var(--border);
border-radius: 0.3rem; cursor: pointer; font-size: 0.85rem;
background: var(--bg); color: var(--text);
}
.modal-btn:hover { background: var(--surface); }
.modal-create { background: var(--accent); color: #fff; border-color: var(--accent); }
.modal-create:hover { opacity: 0.9; }
/* ── Block editor modal ── */
.block-editor-overlay {
position: fixed; inset: 0; z-index: 110;
background: rgba(0,0,0,0.4);
display: none; align-items: center; justify-content: center;
}
.block-editor-overlay.active { display: flex; }
.block-editor-modal {
background: var(--surface); border: 1px solid var(--border);
border-radius: 0.5rem; min-width: 360px; max-width: 480px;
box-shadow: 0 8px 32px rgba(0,0,0,0.2);
display: flex; flex-direction: column; max-height: 80vh;
}
.block-editor-header {
display: flex; align-items: center; justify-content: space-between;
padding: 0.6rem 0.8rem; border-bottom: 1px solid var(--border);
}
.block-editor-title { font-weight: 600; font-size: 0.9rem; }
.block-editor-close {
background: none; border: none; font-size: 1.2rem; cursor: pointer;
color: var(--muted); padding: 0 0.2rem;
}
.block-editor-close:hover { color: var(--text); }
.block-editor-body {
padding: 0.8rem; overflow-y: auto; overflow-x: hidden; flex: 1;
}
.block-editor-body > [data-block] {
position: static !important;
width: 100% !important;
height: auto !important;
border: 1px solid var(--border);
background: var(--bg);
display: flex; flex-direction: column; gap: 0.4rem;
border-radius: 0.3rem; padding: 0.5rem;
}
.block-editor-body input,
.block-editor-body select,
.block-editor-body textarea {
width: 100%; box-sizing: border-box;
}
.block-editor-footer {
display: flex; justify-content: flex-end; gap: 0.4rem;
padding: 0.6rem 0.8rem; border-top: 1px solid var(--border);
}
.block-editor-footer button {
padding: 0.35rem 0.8rem; border-radius: 0.3rem; cursor: pointer;
font-size: 0.8rem; border: 1px solid var(--border);
background: var(--bg); color: var(--text);
}
.block-editor-footer .block-editor-apply {
background: var(--accent); color: #fff; border-color: var(--accent);
}
.block-editor-footer .block-editor-apply:hover { opacity: 0.9; }
.block-editor-footer .block-editor-cancel:hover { background: var(--surface); }
/* Colour picker row inside block editor */
.block-editor-color-row {
display: flex; align-items: center; gap: 0.5rem;
padding: 0.4rem 0.5rem; margin-bottom: 0.5rem;
background: var(--bg); border: 1px solid var(--border);
border-radius: 0.3rem; flex-wrap: wrap; box-sizing: border-box;
max-width: 100%;
}
.block-editor-color-label {
font-size: 0.75rem; font-weight: 600; color: var(--muted);
white-space: nowrap;
}
.block-editor-color-picker {
width: 32px; height: 24px; padding: 0; border: 1px solid var(--border);
border-radius: 3px; cursor: pointer; flex-shrink: 0; max-width: 100%;
}
.block-editor-color-reset {
font-size: 0.7rem; padding: 0.2rem 0.5rem;
border: 1px solid var(--border); border-radius: 3px;
cursor: pointer; background: var(--bg); color: var(--text);
}
.block-editor-color-reset:hover { background: var(--surface); }