You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/components/palabras/palabras.css

419 lines
15 KiB

/**
* `<palabras>` — editor-specific styles.
*
* Layout shell is composed from our components (Flex). This file styles what
* those don't: the editing surface, the active-block selection marker, and the
* FLOATING inspector panel (its own overlay surface — deliberately distinct from
* the docked Words inspector). Content reading styles stay minimal — `scheme-style`
* will own the per-element look next.
*/
[data-palabras] {
display: block;
}
[data-palabras-shell] {
inline-size: 100%;
}
/* The breadcrumb wrapper only delegates clicks — transparent to layout. */
[data-palabras-breadcrumb-wrap] {
display: contents;
}
/* ── Stage: document full-width, panel floats over the frame's top-right ──── */
[data-palabras-stage] {
/* not positioned: the seam line (painted by Words' block-drag controller) is
calculated frame-relative; the inspector panel becomes frame-anchored too
via the rules below. */
}
[data-palabras-doc-card] {
min-block-size: 20rem;
}
/* Make the Words frame the positioned ancestor for the drop-line seam (and the
inspector panel below). The Words.Provider stamps `data-words` on the SAME
div palabras stamps `data-palabras`, so the compound attribute selector
targets this exact element only; standalone <Words> is untouched. */
[data-palabras][data-words] {
position: relative;
}
[data-palabras-doc] {
/* Two real columns: the grip RAIL (its own div with width) + the canvas. */
display: flex;
align-items: stretch;
}
/* Left RAIL — a real column with its OWN width (not padding). Holds the block
grip; `position: relative` so the grip slot positions against it. Same width
on mobile + desktop (option A). */
[data-palabras-rail] {
flex: 0 0 var(--palabras-rail, 32px);
position: relative;
}
/* Canvas — the editing column. `min-inline-size: 0` lets it shrink within the
flex row instead of overflowing. NOT positioned: the drop-line seam painted by
Words' block-drag controller is calculated frame-relative ([data-words]); any
positioned ancestor between the seam and the frame breaks the anchor. */
[data-palabras-canvas] {
flex: 1 1 auto;
min-inline-size: 0;
}
/* Block-grip SLOT — owns the gutter placement. The grip sits at the visited
block's mid-height (PalabrasHandle sets inline `top` = block centre) and
GLIDES between blocks via the `top` transition. The vertical centring
(translateY(-50%)) lives on the slot, NOT the Button, so the Button's
`:active { translateY(1px) }` press transform never fights it. Scoped under
[data-palabras-doc] (0,2,0) to beat the Button recipe's `position`. */
[data-palabras-doc] [data-palabras-handle-slot] {
position: absolute;
/* Grip sits flush with the rail's left edge (no left padding). */
inset-inline-start: 0;
transform: translateY(-50%);
z-index: 5;
transition: top var(--duration-fast, 0.12s) var(--ease-default, ease);
}
/* Action-menu entrance — pin ONE animation. The menu gets TWO competing entrance
animations on open: the sema/motion `present-rise` (applied WHILE the
`data-event` hold is up, ~240ms, because the `open` event is family `emerge`)
and the dropdown recipe's `dropdown-menu-enter` (on `data-state=open`). When
the hold ends the `animation-name` switches → the browser RESTARTS the
animation, snapping opacity back to 0 for a frame. This menu is rendered
in-place (position:fixed but DOM-nested in the rail, NOT portaled), so that
transparent frame reveals the editor blocks behind it — the "block background
flashing over the menu" flicker. Pin the recipe animation with `!important`
so the name never switches and opacity never resets to 0. */
[data-palabras-handle-menu][data-state='open'] {
animation: dropdown-menu-enter var(--duration-fast, 0.12s) var(--ease-out, ease) !important;
}
palabras: menú de inserción (tipos+iconos), columnas visibles y "+" por columna Insertar bloque -> rejilla de tipos: - palabras-block-types.ts (nuevo): lista curada de 10 (Párrafo/Encabezado/Imagen/ Lista/Separador/Cita/Código/Callout/Columnas/Tabla; headings y listas colapsados; imagen incluida) con icono explícito por tipo (los definió el usuario). Sale del registro del motor por id, sin duplicar create(). blockToInsert rellena placeholder en heading/list; imagen via pickImageFile. - Iconos en el menú de acciones (Settings2/LayersPlus/ArrowBigUp/ArrowBigDown/ Trash2). - Menú PORTALIZADO (DropdownMenu.Portal): el slot del grip tiene transform, que lo hace bloque contenedor de los position:fixed -> la colisión de floating-ui se desajustaba y el submenú se volteaba a la izquierda. Portalizar lo saca del slot transformado. Columnas (palabras.css, espejo de Words words.css): - Un bloque de columnas vacío se renderizaba con ALTURA 0 (palabras no carga words.css), y de ahí salían 4 bugs de la MISMA raíz: invisible, grip "se vuelve loco" (las bandas Voronoi-on-Y de blockAtY se degeneran con altura 0), no se podía seleccionar (0px sin área clicable) y el insert caía off-by-one. Fix: flex-row + min-block-size 3em + borde dashed por columna (Words ya lo documentaba: "without this, an empty columns block collapses to 0 height"). "+" por columna (palabras-column-inserter.svelte nuevo): - Overlay "+" sobre cada columna VACÍA -> la misma rejilla (sin Columnas) -> insertBlockInColumn(columnsIdx, colIdx, block) (comando del motor, como el inspector de Words). Posicionado frame-relative, menú portalizado, data-words-external-tool. El "+" desaparece al llenarse la columna. Deuda anotada en continuar-palabras.md (decisión del usuario: al cerrar el componente): labels -> langs, morfo de palabras. Pendiente abierto: grip "fuera de la card" (el offsetParent del slot cae al marco exterior). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
/* Every menu item (main actions + insert tiles + the submenu trigger) is an
icon + label row. The label grows so any trailing chevron (on the "Insertar
bloque" sub-trigger) is pushed to the right edge. */
[data-palabras-handle-menu] [role='menuitem'] {
display: flex;
align-items: center;
gap: var(--space-2);
}
[data-palabras-handle-menu] [role='menuitem'] > span {
flex: 1 1 auto;
}
[data-palabras-handle-menu] [role='menuitem'] svg {
flex: 0 0 auto;
inline-size: 1rem;
block-size: 1rem;
opacity: 0.85;
}
/* "Insertar bloque" submenu — a compact 2-column grid of type tiles. Keyboard
arrow-nav stays vertical over DOM order (mouse-first for now). */
[data-palabras-insert-grid] {
display: grid;
grid-template-columns: repeat(2, minmax(7.5rem, 1fr));
gap: 2px;
}
/* Block grip — the framework <Button> (variant="ghost" size="xs" iconOnly),
copied from Words' gutter grip. The Button recipe owns ALL chrome (padding,
radius, colour, hover, focus ring, press transform) — we add ONLY the drag
affordance cursor, since this Button is primarily a drag handle. Scoped under
[data-palabras-doc] (0,2,0) so it beats the Button recipe's `pointer` cursor
(0,1,0). */
[data-palabras-doc] [data-palabras-handle] {
cursor: grab;
}
[data-palabras-doc] [data-palabras-handle]:active {
cursor: grabbing;
}
[data-palabras-doc] [data-words-content] {
display: block;
outline: none;
}
/* Drop indicator painted by Words' block-drag controller while a block is being
dragged by its grip. The controller positions it frame-relative ([data-words])
at the nearest inter-block seam; the bar spans the target block's width. We
restyle here (Words' own recipe is not loaded under palabras). */
[data-palabras-canvas] [data-words-block-drop-line] {
position: absolute;
z-index: 5;
block-size: 2px;
margin-block-start: -1px;
border-radius: 1px;
background: var(--color-primary-solid);
pointer-events: none;
}
/* Kill the archetype focus ring (box-shadow) on the editing surface — the caret
is the focus indicator; otherwise the whole document gets boxed in violet. */
[data-palabras-doc] [data-words-content][data-archetype]:focus-visible {
box-shadow: none;
}
[data-palabras-doc] [data-words-content] :where(h1, h2, h3, p) {
margin-block: 0 0.6em;
}
/* Selection marker for the active/selected block — dotted (NOT the solid focus
ring, which is suppressed above). Stamped by WordsActivate on the active
block element. */
[data-palabras-doc] [data-words-active] {
outline: 1.5px dashed var(--color-primary-border);
outline-offset: 6px;
border-radius: var(--radius-sm);
}
palabras: menú de inserción (tipos+iconos), columnas visibles y "+" por columna Insertar bloque -> rejilla de tipos: - palabras-block-types.ts (nuevo): lista curada de 10 (Párrafo/Encabezado/Imagen/ Lista/Separador/Cita/Código/Callout/Columnas/Tabla; headings y listas colapsados; imagen incluida) con icono explícito por tipo (los definió el usuario). Sale del registro del motor por id, sin duplicar create(). blockToInsert rellena placeholder en heading/list; imagen via pickImageFile. - Iconos en el menú de acciones (Settings2/LayersPlus/ArrowBigUp/ArrowBigDown/ Trash2). - Menú PORTALIZADO (DropdownMenu.Portal): el slot del grip tiene transform, que lo hace bloque contenedor de los position:fixed -> la colisión de floating-ui se desajustaba y el submenú se volteaba a la izquierda. Portalizar lo saca del slot transformado. Columnas (palabras.css, espejo de Words words.css): - Un bloque de columnas vacío se renderizaba con ALTURA 0 (palabras no carga words.css), y de ahí salían 4 bugs de la MISMA raíz: invisible, grip "se vuelve loco" (las bandas Voronoi-on-Y de blockAtY se degeneran con altura 0), no se podía seleccionar (0px sin área clicable) y el insert caía off-by-one. Fix: flex-row + min-block-size 3em + borde dashed por columna (Words ya lo documentaba: "without this, an empty columns block collapses to 0 height"). "+" por columna (palabras-column-inserter.svelte nuevo): - Overlay "+" sobre cada columna VACÍA -> la misma rejilla (sin Columnas) -> insertBlockInColumn(columnsIdx, colIdx, block) (comando del motor, como el inspector de Words). Posicionado frame-relative, menú portalizado, data-words-external-tool. El "+" desaparece al llenarse la columna. Deuda anotada en continuar-palabras.md (decisión del usuario: al cerrar el componente): labels -> langs, morfo de palabras. Pendiente abierto: grip "fuera de la card" (el offsetParent del slot cae al marco exterior). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
/* Columns block — flex layout, MIRRORED FROM Words' `words.css` (palabras does
NOT load Words' recipe, so without this the block gets no layout or height).
An empty columns block otherwise collapses to 0px: invisible AND it breaks the
grip — a zero-height block makes the rail's vertical block-targeting bands
(`blockAtY`, Voronoi-on-Y) DEGENERATE, so the grip jumps and the block can't
be selected or targeted, and inserts land off-by-one. `min-block-size` + the
dashed per-column outline give it real, discoverable, clickable structure. */
[data-palabras-doc] [data-words-block='columns'] {
display: flex;
flex-direction: row;
gap: var(--space-3);
margin-block: var(--space-3) 0;
align-items: stretch;
}
[data-palabras-doc] [data-words-block='columns'] [data-words-column] {
display: flex;
flex-direction: column;
min-inline-size: 0;
min-block-size: 3em;
padding: 0;
border: 1px dashed var(--color-neutral-border);
border-radius: var(--radius-sm);
transition: border-color var(--duration-fast, 0.12s) var(--ease-default, ease);
}
[data-palabras-doc] [data-words-block='columns'] [data-words-column]:hover,
[data-palabras-doc] [data-words-block='columns'] [data-words-column]:focus-within {
border-color: var(--color-content-primary);
}
/* Reset the universal block-rhythm margin on each column's first nested block. */
[data-palabras-doc] [data-words-block='columns'] [data-words-column] > *:first-child {
margin-block-start: 0;
}
/* Per-column "+" inserter — an overlay centred over each EMPTY column. Absolute
so it anchors to the FRAME (not the canvas — a positioned canvas breaks the
drop-line seam's frame-relative anchor); the inline left/top are
frame-relative. The menu is portaled, so the centring transform here doesn't
become the menu's containing block. */
[data-palabras-canvas] [data-palabras-column-inserter] {
position: absolute;
transform: translate(-50%, -50%);
z-index: 4;
}
/* The "+" itself — a fully round, bordered, ELEVATED button (overrides the
ghost Button's transparent chrome). */
[data-palabras-canvas] [data-palabras-column-inserter] [data-palabras-column-inserter-button] {
background: var(--color-surface-default);
border: 1px solid var(--color-neutral-border);
border-radius: 999px;
box-shadow:
0 4px 12px -2px rgb(0 0 0 / 0.22),
0 2px 4px -1px rgb(0 0 0 / 0.16);
color: var(--color-content-muted);
}
[data-palabras-canvas] [data-palabras-column-inserter] [data-palabras-column-inserter-button]:hover {
border-color: var(--color-content-primary);
color: var(--color-content-primary);
}
palabras: menú de inserción (tipos+iconos), columnas visibles y "+" por columna Insertar bloque -> rejilla de tipos: - palabras-block-types.ts (nuevo): lista curada de 10 (Párrafo/Encabezado/Imagen/ Lista/Separador/Cita/Código/Callout/Columnas/Tabla; headings y listas colapsados; imagen incluida) con icono explícito por tipo (los definió el usuario). Sale del registro del motor por id, sin duplicar create(). blockToInsert rellena placeholder en heading/list; imagen via pickImageFile. - Iconos en el menú de acciones (Settings2/LayersPlus/ArrowBigUp/ArrowBigDown/ Trash2). - Menú PORTALIZADO (DropdownMenu.Portal): el slot del grip tiene transform, que lo hace bloque contenedor de los position:fixed -> la colisión de floating-ui se desajustaba y el submenú se volteaba a la izquierda. Portalizar lo saca del slot transformado. Columnas (palabras.css, espejo de Words words.css): - Un bloque de columnas vacío se renderizaba con ALTURA 0 (palabras no carga words.css), y de ahí salían 4 bugs de la MISMA raíz: invisible, grip "se vuelve loco" (las bandas Voronoi-on-Y de blockAtY se degeneran con altura 0), no se podía seleccionar (0px sin área clicable) y el insert caía off-by-one. Fix: flex-row + min-block-size 3em + borde dashed por columna (Words ya lo documentaba: "without this, an empty columns block collapses to 0 height"). "+" por columna (palabras-column-inserter.svelte nuevo): - Overlay "+" sobre cada columna VACÍA -> la misma rejilla (sin Columnas) -> insertBlockInColumn(columnsIdx, colIdx, block) (comando del motor, como el inspector de Words). Posicionado frame-relative, menú portalizado, data-words-external-tool. El "+" desaparece al llenarse la columna. Deuda anotada en continuar-palabras.md (decisión del usuario: al cerrar el componente): labels -> langs, morfo de palabras. Pendiente abierto: grip "fuera de la card" (el offsetParent del slot cae al marco exterior). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4 months ago
/* ── Floating inspector panel ─────────────────────────────────────────────── */
[data-palabras-panel-card] {
position: absolute;
inset-block-start: var(--space-4);
inset-inline-end: var(--space-4);
inline-size: 17rem;
z-index: 10;
padding: var(--space-4);
border: 1px solid var(--color-neutral-border);
border-radius: var(--radius-lg);
background: var(--color-surface-overlay);
/* Elevation = it reads as a floating window, not a docked sidebar. */
box-shadow: var(--shadow-lg, 0 16px 40px -12px rgb(0 0 0 / 0.6));
font-family: var(--font-ui);
}
/* Header: dot · title (grows) · trash */
[data-palabras-panel-head] {
display: flex;
align-items: center;
gap: var(--space-2);
margin-block-end: var(--space-2);
/* The header is the drag handle (PalabrasPanel). */
cursor: move;
user-select: none;
touch-action: none;
}
[data-palabras-panel-dot] {
flex: 0 0 auto;
inline-size: 0.5rem;
block-size: 0.5rem;
border-radius: 50%;
}
[data-palabras-panel-title] {
flex: 1 1 auto;
font-size: var(--font-size-md);
font-weight: 600;
color: var(--color-content-primary);
}
/* Section: collapsible title + fields */
[data-palabras-panel-section] {
margin-block-start: var(--space-3);
}
[data-palabras-panel-section-title] {
display: flex;
align-items: center;
justify-content: space-between;
inline-size: 100%;
padding: 0;
border: none;
background: none;
cursor: pointer;
font: inherit;
font-size: var(--font-size-xs);
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--color-content-muted);
}
[data-palabras-panel-section-title] svg {
inline-size: 0.85rem;
block-size: 0.85rem;
opacity: 0.7;
}
[data-palabras-panel-fields] {
margin-block-start: var(--space-3);
}
/* Fields */
[data-palabras-field] {
display: flex;
flex-direction: column;
gap: var(--space-1-5);
}
[data-palabras-field] + [data-palabras-field] {
margin-block-start: var(--space-3);
}
/* Inline fields (toggle · anchor · colour · number): a 2-column grid so the
label is one column and the control the other — every control's right edge
lines up across rows. */
[data-palabras-field][data-inline] {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: var(--space-3);
}
/* The control column right-aligns its content (colour swatch / number field). */
[data-palabras-field][data-inline] > :not([data-palabras-field-label]) {
justify-self: end;
}
[data-palabras-field-label] {
font-size: var(--font-size-sm);
color: var(--color-content-primary);
}
[data-palabras-field-todo] {
font-size: var(--font-size-xs);
font-style: italic;
color: var(--color-content-muted);
}
/* Anchor "chip" — monospace slug, compact, right-aligned. */
[data-palabras-text] {
inline-size: 7rem;
padding: var(--space-1) var(--space-2);
border: 1px solid var(--color-neutral-border);
border-radius: var(--radius-sm);
background: var(--color-surface-default);
color: var(--color-content-primary);
font: inherit;
font-size: var(--font-size-xs);
font-family: var(--font-mono);
text-align: end;
}
[data-palabras-text]:focus-visible {
outline: none;
border-color: var(--color-focus-ring);
}
/* Footer: themed-appearance line */
[data-palabras-panel-foot] {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-2);
margin-block-start: var(--space-4);
padding-block-start: var(--space-3);
border-block-start: 1px solid var(--color-neutral-border);
font-size: var(--font-size-sm);
color: var(--color-content-muted);
}
[data-palabras-panel-edit] {
border: none;
background: none;
color: var(--color-primary-text);
font: inherit;
font-size: var(--font-size-sm);
cursor: pointer;
}
[data-palabras-panel-edit][disabled] {
opacity: 0.6;
cursor: default;
}
[data-palabras-panel-empty] {
margin: 0;
font-size: var(--font-size-sm);
color: var(--color-content-muted);
}
/* ── Appearance popover (2nd window, opened by "Editar") ───────────────────── */
[data-palabras-appearance] {
position: absolute;
inset-block-start: var(--space-4);
/* Sits just left of the main panel (17rem wide). */
inset-inline-end: calc(17rem + var(--space-3));
inline-size: 16rem;
z-index: 11;
padding: var(--space-4);
border: 1px solid var(--color-neutral-border);
border-radius: var(--radius-lg);
background: var(--color-surface-overlay);
box-shadow: var(--shadow-lg, 0 16px 40px -12px rgb(0 0 0 / 0.6));
font-family: var(--font-ui);
}
/* NumberField in the appearance popover — compact, fixed width so the grid's
control column stays tidy. */
[data-palabras-appearance] [data-number-field] {
inline-size: 6rem;
}
/* ── Help line ────────────────────────────────────────────────────────────── */
[data-palabras-help] {
margin: 0;
font-size: var(--font-size-sm);
color: var(--color-content-muted);
}
[data-palabras-help] kbd {
font: inherit;
padding-inline: var(--space-1);
border: 1px solid var(--color-neutral-border);
border-radius: var(--radius-sm);
background: var(--color-surface-muted);
}
/* ── Mobile: the floating panels become bottom drawers ────────────────────── */
@media (max-width: 40rem) {
/* The rail + grip stay identical to desktop (option A). Only the floating
panels change to bottom drawers below. */
[data-palabras-panel-card],
[data-palabras-appearance] {
position: fixed;
inset: auto 0 0 0;
inline-size: auto;
max-block-size: 70vh;
overflow-y: auto;
border-inline: none;
border-block-end: none;
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
/* Anchored bottom drawer — ignore any drag offset from the desktop float. */
transform: none !important;
}
/* Appearance drawer sits above the main one. */
[data-palabras-appearance] {
z-index: 12;
}
}

Powered by TurnKey Linux.