diff --git a/docs/architecture/ribbon.md b/docs/architecture/ribbon.md
index a43e772..32b29c4 100644
--- a/docs/architecture/ribbon.md
+++ b/docs/architecture/ribbon.md
@@ -100,7 +100,7 @@ at every height. A flex row cannot reserve width in part of its height, so it mo
| --- | --- |
| `Ribbon.svelte` | Shell, tab state, the File menu, which contextual tabs are shown |
| `RibbonGroup.svelte` | A group: its controls, its visible label, Word's ↘ dialog launcher |
-| `RibbonButton.svelte` | `big` / `small` / `icon`, plus the split button. Hover paints the **icon box**, not the whole button |
+| `RibbonButton.svelte` | `big` / `small` / `icon`, plus the split button. Hover paints the **icon box**, not the whole button. A big label wraps onto two lines at a 78px cap and its caret rides beside the icon, so a three-word label costs width instead of a third row |
| `RibbonMenu.svelte` | The dropdown panel; its look is global CSS, since its rows come from a caller's snippet |
| `Icon.svelte`, `icons.ts` | Path data on a 16-unit canvas. `pinnedStroke(size)` holds the painted stroke at ~1.5px on large glyphs and ~1.1px on small ones, so 14px and 28px icons read as one family |
| `menu.svelte.ts` | The one open-menu id, `anchored`, `pinPanels`, `clickOutside` |
diff --git a/src/lib/components/ribbon/RibbonButton.svelte b/src/lib/components/ribbon/RibbonButton.svelte
index 1fb5ed5..c2e01bb 100644
--- a/src/lib/components/ribbon/RibbonButton.svelte
+++ b/src/lib/components/ribbon/RibbonButton.svelte
@@ -36,29 +36,23 @@
const ICON_SIZE = { big: 28, small: 14, icon: 20 } as const;
-{#snippet face(withLabel = true)}
+{#snippet face()}
{#if content}{@render content()}
{:else if icon}{/if}
- {#if caret && !onCaret && variant === 'icon'}
+ {#if caret && !onCaret && variant !== 'small'}
{/if}
- {#if withLabel && label && variant !== 'icon'}{label}{/if}
+ {#if label && variant !== 'icon'}{label}{/if}
{#if caret && !onCaret && variant === 'small'}{/if}
-
- {#if variant === 'big' && !onCaret}
- {#if caret}{/if}
- {/if}
{/snippet}
{#if caret && onCaret}
- {@const stacked = variant === 'big'}
-
+
@@ -163,12 +156,12 @@
color: inherit;
}
- /* Rides closer to the label than the 4px column gap: the two read as one line. */
- .rb-stack-caret {
- display: flex;
- height: 8px;
- margin-top: -3px;
- color: var(--w-text-dim);
+ /* The cap is what makes the wrap happen: unwrapped, a three-word label is twice
+ the width of the icon above it. Two lines fit the band, a third is clipped. */
+ .rb-big .rb-label {
+ max-width: 78px;
+ white-space: normal;
+ text-align: center;
}
/* Split button: the two halves read as one control, so the hover outline sits on
@@ -194,20 +187,6 @@
cursor: pointer;
}
- /* A big split button stacks, as in Word: the icon runs the command, the label
- and the caret under it open the menu. Icon, label and caret each get their
- own line — abreast, the caret widens the button by its own width. */
- .rb-split-col { flex-direction: column; }
- .rb-split-col .rb-big { padding: 2px 6px 0; }
-
- .rb-split-col .rb-caret {
- flex-direction: column;
- width: auto;
- padding: 0 6px 1px;
- border-radius: 0 0 3px 3px;
- color: var(--w-text);
- }
-
.rb-caret:hover:not(:disabled) { background: var(--w-pressed); }
.rb-caret:disabled { opacity: 0.4; cursor: default; }
.rb-caret.active { background: var(--w-active); }
diff --git a/src/lib/components/ribbon/tabs/TableTabs.svelte b/src/lib/components/ribbon/tabs/TableTabs.svelte
index e727fae..de346dc 100644
--- a/src/lib/components/ribbon/tabs/TableTabs.svelte
+++ b/src/lib/components/ribbon/tabs/TableTabs.svelte
@@ -338,8 +338,7 @@
.rb-menu-wrap { position: relative; }
/* Wrapped onto two lines, as in Word — on one they are half the group's width.
- `min-content` is what keeps the button off the label's unwrapped width, and
- the caret slot goes because the two lines already reach the group's foot. */
+ `min-content` breaks at every space, tighter than the button's own cap. */
.inserts {
display: flex;
align-items: stretch;
@@ -355,8 +354,6 @@
line-height: 13px;
}
- .inserts :global(.rb-stack-caret) { display: none; }
-
/* A big button wrapped in the trigger the popover hangs from; `anchored` drops
the popover below the whole band, like every other ribbon menu. */
.split-trigger {