/* Floor plan editor - Track C. B60 OS tokens only (--ds-* via main.css aliases). */

/* The page area has no padding on this full-bleed screen (design-system.css),
   so the floor pills and the editor sat flush against the side menu while the
   page title above them was indented. Same inset as the title. */
.floor-plan-page {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
    min-height: calc(100vh - 120px);
    height: calc(100vh - 120px);
    box-sizing: border-box;
}

/* Two classes, to outrank design-system.css's ".page-content > .ds-root
   { padding: 0 }", which is there to stop double padding -- on this page the
   shell adds none, so this is the only inset there is. */
.page-content > .floor-plan-page {
    padding: var(--ds-space-2) var(--ds-pad-page-inline) var(--ds-pad-page-inline);
}

.fp-shell {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 304px;
    gap: var(--ds-space-4);
    align-items: stretch;
    flex: 1;
    min-height: 0;
}

@media (max-width: 1023px) {
    .fp-shell {
        grid-template-columns: 1fr;
    }
    .fp-props-panel {
        order: 2;
    }

    /* Stacked, the page cannot be one screen high: the toolbar, the map and
       the table list were squeezed into it and drawn over each other (the
       list card covered Templates, Undo and Redo sat on its title). The page
       grows and scrolls; the map keeps a usable height. */
    .floor-plan-page {
        height: auto;
        min-height: 0;
    }
    .floor-plan-page .fp-shell,
    .floor-plan-page .fp-editor-wrap {
        flex: none;
    }
    .floor-plan-page .fp-stage-outer {
        flex: none;
        height: clamp(320px, 60vh, 560px);
    }
    .floor-plan-page .fp-props-panel {
        overflow: visible;
    }
}

.fp-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ds-space-2);
    padding: var(--ds-space-3) var(--ds-space-4);
    background: var(--ds-bg-surface);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-lg);
}

.fp-toolbar-group {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    flex-wrap: wrap;
}

.fp-toolbar-divider {
    width: 1px;
    height: 28px;
    background: var(--ds-border-default);
    margin-inline: var(--ds-space-1);
}

.fp-floor-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ds-space-2);
    margin-block-end: var(--ds-space-3);
}

/* One pill = the floor's name plus its remove control. The border lives on the
   pill so the two sit inside a single shape rather than reading as two
   buttons that happen to be next to each other. */
.fp-floor-pill {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--ds-border-default);
    background: var(--ds-bg-surface);
    border-radius: var(--ds-radius-pill);
    overflow: hidden;
    transition: background var(--ds-motion-hover) var(--ds-ease-standard),
                border-color var(--ds-motion-hover) var(--ds-ease-standard);
}

.fp-floor-tab {
    border: 0;
    background: transparent;
    color: var(--ds-text-secondary);
    padding: 8px 16px;
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    cursor: pointer;
    transition: color var(--ds-motion-hover) var(--ds-ease-standard);
}

.fp-floor-pill.is-active {
    background: var(--ds-primary);
    border-color: var(--ds-primary);
}

.fp-floor-pill.is-active .fp-floor-tab,
.fp-floor-pill.is-active .fp-floor-remove {
    color: var(--ds-text-on-accent);
}

.fp-floor-remove {
    border: 0;
    background: transparent;
    color: var(--ds-text-tertiary);
    padding: 0 8px 0 2px;
    font-size: var(--ds-text-md);
    line-height: 1;
    cursor: pointer;
    transition: color var(--ds-motion-hover) var(--ds-ease-standard);
}

:where(.can-hover) .fp-floor-remove:hover {
    color: var(--ds-danger);
}

/* The pill turns into this while its name is being edited, and has to keep the
   row from reflowing under the cursor -- hence the matching height and pill
   radius rather than an inherited .ds-input. */
.fp-floor-rename {
    border: 1px solid var(--ds-primary);
    background: var(--ds-bg-surface);
    color: var(--ds-text-primary);
    border-radius: var(--ds-radius-pill);
    padding: 8px 16px;
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    min-width: 120px;
    max-width: 220px;
}

.fp-floor-add {
    border: 1px dashed var(--ds-border-default);
    background: transparent;
    color: var(--ds-text-secondary);
    border-radius: var(--ds-radius-pill);
    padding: 8px 16px;
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    cursor: pointer;
    transition: color var(--ds-motion-hover) var(--ds-ease-standard),
                border-color var(--ds-motion-hover) var(--ds-ease-standard);
}

:where(.can-hover) .fp-floor-add:hover {
    color: var(--ds-primary);
    border-color: var(--ds-primary);
}

/* Shown only while a palette shape is armed, to say where the next click goes.
   Primary-coloured so it reads as an active mode rather than as help text. */
.fp-place-hint {
    font-size: var(--ds-text-xs);
    font-weight: 600;
    color: var(--ds-primary);
    white-space: nowrap;
}

.fp-place-hint[hidden] {
    display: none;
}

.fp-save-indicator {
    font-size: var(--ds-text-xs);
    color: var(--ds-text-tertiary);
    min-width: 72px;
    text-align: end;
}

.fp-save-indicator.is-saving {
    color: var(--ds-primary);
}

.fp-save-indicator.is-error {
    color: var(--ds-danger);
}

.fp-editor-wrap {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
    min-width: 0;
    min-height: 0;
    flex: 1;
}

.fp-stage-outer {
    position: relative;
    flex: 1;
    min-height: 320px;
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-bg-inset);
    overflow: hidden;
    touch-action: none;
    user-select: none;
}

.fp-stage {
    position: absolute;
    inset: 0;
    overflow: hidden;
    cursor: default;
}

/* An empty floor's first step, over the middle of the canvas. Only the card
   takes taps; the rest of the floor stays live underneath. */
.fp-start {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: grid;
    place-items: center;
    padding: var(--ds-space-4);
    pointer-events: none;
}

.fp-start[hidden] {
    display: none;
}

.fp-start-card {
    max-inline-size: 440px;
    padding: var(--ds-space-6);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-bg-surface);
    box-shadow: var(--ds-shadow-card);
    text-align: center;
    pointer-events: auto;
}

.fp-start-title {
    margin: 0;
    font-size: var(--ds-text-lg);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-primary);
}

.fp-start-desc {
    margin: var(--ds-space-2) 0 var(--ds-space-4);
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
}

.fp-start-layouts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--ds-space-2);
}

.fp-stage.is-panning {
    cursor: grab;
}

.fp-stage.is-panning:active {
    cursor: grabbing;
}

.fp-viewport {
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: 0 0;
    will-change: transform;
}

.fp-floor-surface {
    position: relative;
    background: var(--ds-bg-surface);
    box-shadow: var(--ds-shadow-card);
    border-radius: var(--ds-radius-md);
    overflow: hidden;
}

.fp-floor-surface.is-grid {
    background-color: var(--ds-bg-surface);
    background-image: radial-gradient(circle, var(--ds-border-strong) 1px, transparent 1px);
    background-size: 16px 16px;
    background-position: 0 0;
}

.fp-bg-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: fill;
    pointer-events: none;
}

.fp-tables-layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.fp-table {
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: center center;
    will-change: transform;
    pointer-events: auto;
    touch-action: none;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ds-bg-surface);
    border: 2px solid var(--ds-border-default);
    box-shadow: var(--ds-shadow-card);
    color: var(--ds-text-primary);
    font-size: 12px;
    font-weight: var(--ds-fw-semibold);
    text-align: center;
    padding: 4px;
    cursor: move;
}

.fp-table.is-selected {
    border-color: var(--ds-primary);
    box-shadow: 0 0 0 2px var(--ds-primary-tint), var(--ds-shadow-pop);
    z-index: 4;
}

.fp-table.is-round {
    border-radius: 50%;
}

.fp-table.is-square,
.fp-table.is-rectangle {
    border-radius: var(--ds-radius-md);
}

.fp-table.is-booth {
    border-radius: var(--ds-radius-lg) var(--ds-radius-lg) var(--ds-radius-sm) var(--ds-radius-sm);
}

.fp-table.is-bar_stool {
    border-radius: 50%;
    min-width: 32px;
    min-height: 32px;
}

.fp-table-label {
    pointer-events: none;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

.fp-table-seats {
    display: block;
    font-size: 10px;
    font-weight: var(--ds-fw-normal);
    color: var(--ds-text-secondary);
}

.fp-handle {
    position: absolute;
    width: 10px;
    height: 10px;
    background: var(--ds-bg-surface);
    border: 2px solid var(--ds-primary);
    border-radius: 2px;
    box-sizing: border-box;
    pointer-events: auto;
    touch-action: none;
    z-index: 6;
}

.fp-handle-nw { top: -6px; left: -6px; cursor: nwse-resize; }
.fp-handle-ne { top: -6px; right: -6px; cursor: nesw-resize; }
.fp-handle-sw { bottom: -6px; left: -6px; cursor: nesw-resize; }
.fp-handle-se { bottom: -6px; right: -6px; cursor: nwse-resize; }

.fp-rotate-handle {
    position: absolute;
    top: -28px;
    left: 50%;
    width: 14px;
    height: 14px;
    margin-left: -8px;
    border-radius: 50%;
    background: var(--ds-primary);
    border: 2px solid var(--ds-bg-surface);
    cursor: grab;
    pointer-events: auto;
    touch-action: none;
    z-index: 6;
}

.fp-rotate-handle::after {
    content: '';
    position: absolute;
    top: 14px;
    left: 50%;
    width: 1px;
    height: 10px;
    background: var(--ds-primary);
    transform: translateX(-50%);
}

.fp-marquee {
    position: absolute;
    border: 1px dashed var(--ds-primary);
    background: var(--ds-primary-tint);
    pointer-events: none;
    z-index: 8;
}

.fp-zoom-controls {
    position: absolute;
    inset-inline-start: var(--ds-space-3);
    bottom: var(--ds-space-3);
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-1);
    z-index: 10;
}

.fp-zoom-btn {
    width: 36px;
    height: 36px;
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-md);
    background: var(--ds-bg-surface);
    color: var(--ds-text-primary);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    box-shadow: var(--ds-shadow-card);
}

/* An icon each (floor_plan.js), centred; they were typed as +, - and []. */
.fp-zoom-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

:where(.can-hover) .fp-zoom-btn:hover {
    border-color: var(--ds-primary);
    color: var(--ds-primary);
}

.fp-zoom-readout {
    font-size: var(--ds-text-xs);
    text-align: center;
    color: var(--ds-text-secondary);
    background: var(--ds-bg-surface);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-sm);
    padding: 2px 8px;
}

.fp-palette {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ds-space-2);
}

.fp-palette-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    min-width: 64px;
    padding: var(--ds-space-2);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-md);
    background: var(--ds-bg-surface);
    cursor: grab;
    font-size: var(--ds-text-xs);
    color: var(--ds-text-secondary);
    touch-action: none;
}

.fp-palette-item.is-active {
    border-color: var(--ds-primary);
    background: var(--ds-primary-tint);
    color: var(--ds-primary);
}

.fp-palette-shape {
    width: 36px;
    height: 28px;
    border: 2px solid var(--ds-border-strong);
    background: var(--ds-bg-inset);
}

.fp-palette-shape.is-round { border-radius: 50%; width: 32px; height: 32px; }
.fp-palette-shape.is-square { border-radius: var(--ds-radius-sm); }
.fp-palette-shape.is-rectangle { width: 44px; border-radius: var(--ds-radius-sm); }
.fp-palette-shape.is-booth { width: 48px; border-radius: var(--ds-radius-md) var(--ds-radius-md) 4px 4px; }
.fp-palette-shape.is-bar_stool { width: 20px; height: 20px; border-radius: 50%; }

.fp-props-panel {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
    padding: var(--ds-space-4);
    background: var(--ds-bg-surface);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-lg);
    min-height: 0;
    overflow: auto;
}

.fp-props-panel h3 {
    margin: 0;
    font-size: var(--ds-text-md);
    font-weight: var(--ds-fw-semibold);
}

.fp-props-empty {
    color: var(--ds-text-secondary);
    font-size: var(--ds-text-sm);
}

.fp-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.fp-field label {
    font-size: var(--ds-text-xs);
    color: var(--ds-text-secondary);
    font-weight: var(--ds-fw-medium);
}

.fp-readout {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-primary);
    padding: var(--ds-space-2) var(--ds-space-3);
    background: var(--ds-bg-inset);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-sm);
}

.fp-section-label {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-primary);
}

.fp-floor-props {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
}

.fp-bg-controls {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
    padding: var(--ds-space-3);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-md);
    background: var(--ds-bg-inset);
}

.fp-bg-preview {
    width: 100%;
    height: 72px;
    object-fit: cover;
    border-radius: var(--ds-radius-sm);
    border: 1px solid var(--ds-border-default);
    background: var(--ds-bg-surface);
}

.fp-bg-preview.is-empty {
    display: none;
}

.fp-inline-error {
    margin: 0;
    color: var(--ds-danger);
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-semibold);
}

.fp-inline-error[hidden] {
    display: none;
}

.fp-toggle.is-on {
    background: var(--ds-primary-tint);
    border-color: var(--ds-primary);
    color: var(--ds-primary);
}

/* --------------------------------------------------------- all-tables list

   Every table on the floor, listed regardless of whether it can be found on
   the canvas. A table dragged past the edge, or dropped exactly on top of
   another, is invisible and therefore unselectable -- the only sign it exists
   is its number appearing in the POS table picker. This is the way back to it.

   Sorted by number, because that is the identity the rest of the app uses. */
.fp-table-list-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-2);
    margin-block-start: var(--ds-space-2);
    padding-block-start: var(--ds-space-3);
    border-block-start: 1px solid var(--ds-border-default);
}

/* The list only shows while no table is selected, so nothing sits above
   it and the rule over its title was a stray line at the top of the card. */
#fpTableProps[hidden] + .fp-table-list-head {
    margin-block-start: 0;
    padding-block-start: 0;
    border-block-start: 0;
}

.fp-table-list-count {
    font-size: var(--ds-text-xs);
    color: var(--ds-text-tertiary);
    font-variant-numeric: tabular-nums;
}

.fp-table-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    /* Scrolls inside the panel and takes the room the panel has, with Floor
       settings kept below it. It was capped at 240px, which on taller rows
       (number, name, seats) showed five tables. */
    flex: 1 1 auto;
    min-height: 120px;
    overflow-y: auto;
}

.fp-table-row {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    padding: 8px var(--ds-space-2);
    border-radius: var(--ds-radius-sm);
    cursor: pointer;
    font-size: var(--ds-text-sm);
    /* 32px: this is a touch target on the till, not just a list row. */
    min-height: 32px;
}

:where(.can-hover) .fp-table-row:hover {
    background: var(--ds-bg-inset);
}

.fp-table-row.is-selected {
    background: var(--ds-primary-tint);
    color: var(--ds-primary);
}

.fp-table-row-num {
    font-weight: var(--ds-fw-semibold);
    font-variant-numeric: tabular-nums;
    min-width: 2ch;
    text-align: end;
}

.fp-table-row-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--ds-text-secondary);
}

.fp-table-row.is-selected .fp-table-row-name {
    color: inherit;
}

/* The reason a row is here at all rather than being found on the canvas. */
.fp-table-row-fix {
    border: 1px solid var(--ds-warning);
    background: transparent;
    color: var(--ds-warning);
    border-radius: var(--ds-radius-sm);
    font-size: var(--ds-text-xs);
    padding: 1px 8px;
    cursor: pointer;
    white-space: nowrap;
}

.fp-table-row-del {
    border: none;
    background: transparent;
    color: var(--ds-text-tertiary);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    padding: 2px 8px;
    border-radius: var(--ds-radius-sm);
}

:where(.can-hover) .fp-table-row-del:hover {
    background: var(--ds-danger-tint, rgba(220, 38, 38, .1));
    color: var(--ds-danger);
}

/* Floor settings are set once and then left alone, so they collapse. They used
   to sit at the top of the panel, which on a 730px till pushed the table list
   off the bottom -- the one thing the panel exists to make findable. */
.fp-floor-settings {
    border-block-start: 1px solid var(--ds-border-default);
    padding-block-start: var(--ds-space-3);
    margin-block-start: var(--ds-space-1);
}

.fp-floor-settings > summary {
    cursor: pointer;
    font-size: var(--ds-text-md);
    font-weight: var(--ds-fw-semibold);
    /* A real touch target on the till, not just a text line. */
    min-height: 32px;
    display: flex;
    align-items: center;
}

.fp-floor-settings[open] > summary {
    margin-block-end: var(--ds-space-3);
}

/* Align/distribute need two or more tables. Disabled below that, rather than
   returning silently, which read as a dead button. */
.fp-multi:disabled {
    opacity: .45;
    cursor: not-allowed;
}

.fp-selection-count {
    font-size: var(--ds-text-xs);
    color: var(--ds-text-tertiary);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.fp-template-label {
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-secondary);
    white-space: nowrap;
}

.fp-toolbar-group #fpTemplateSelect {
    min-width: 9rem;
    max-width: 12rem;
}

/* Label, list and Apply stay on one line: "Apply" used to drop under the
   list on its own, a third toolbar row for one button. */
.fp-toolbar-group.fp-templates {
    flex: none;
    flex-wrap: nowrap;
}

/* The way back from a selected table to the list. A real control, because the
   panel sits on the far side of the screen from the canvas and "click empty
   space to deselect" is not a route anyone finds -- the reported workaround was
   reloading the page. */
.fp-back-to-list {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    align-self: flex-start;
    background: none;
    border: none;
    padding: 4px 0;
    /* 32px so it is a real target on a touch till, not just a text link. */
    min-height: 32px;
    color: var(--ds-primary);
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    cursor: pointer;
}

:where(.can-hover) .fp-back-to-list:hover {
    text-decoration: underline;
}

.fp-detail-title {
    font-weight: var(--ds-fw-semibold);
    font-size: var(--ds-text-md);
    margin-block-end: var(--ds-space-2);
}

/* ---- Tools and the panel's three views (2026-10-11) ------------------- */

/* Select / Move view: a segmented pair, so which one is on is never a guess. */
.fp-tools {
    gap: 0;
    padding: 3px;
    background: var(--ds-bg-inset);
    border-radius: var(--ds-radius-md);
}

.fp-tool {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 40px;
    padding: 0 var(--ds-space-3);
    border: 0;
    border-radius: var(--ds-radius-sm);
    background: transparent;
    color: var(--ds-text-secondary);
    font: inherit;
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    cursor: pointer;
}

:where(.can-hover) .fp-tool:hover {
    color: var(--ds-text-primary);
}

.fp-tool.is-active {
    background: var(--ds-bg-surface);
    color: var(--ds-primary);
    box-shadow: 0 1px 2px rgba(20, 20, 40, 0.12);
}

.fp-tool:focus-visible {
    outline: 2px solid var(--ds-primary);
    outline-offset: 1px;
}

/* The hand: grab over the floor and over tables (and their handles), grabbing
   while it moves. */
.fp-stage.is-hand,
.fp-stage.is-hand .fp-table,
.fp-stage.is-hand .fp-handle,
.fp-stage.is-hand .fp-rotate-handle {
    cursor: grab;
}

.fp-stage.is-panning,
.fp-stage.is-panning .fp-table {
    cursor: grabbing;
}

.fp-panel-hint {
    margin: 0;
    font-size: var(--ds-text-xs);
    color: var(--ds-text-tertiary);
}

/* Tight enough that a table's whole view, Delete included, fits the panel
   on a 875px screen without scrolling. */
.fp-detail {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
}

.fp-detail-hero {
    display: flex;
    align-items: center;
    gap: var(--ds-space-3);
}

.fp-detail-hero-text {
    min-width: 0;
}

.fp-detail-hero .fp-detail-title {
    margin: 0;
    font-size: var(--ds-text-lg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fp-detail-sub {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
}

/* The table number as a badge: it is the table's identity, so it leads. */
.fp-num-badge {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    height: 44px;
    padding: 0 8px;
    box-sizing: border-box;
    border-radius: var(--ds-radius-md);
    background: var(--ds-primary-tint);
    color: var(--ds-primary);
    font-size: var(--ds-text-lg);
    font-weight: var(--ds-fw-semibold);
    font-variant-numeric: tabular-nums;
}

.fp-num-badge.is-sm {
    min-width: 32px;
    height: 32px;
    border-radius: var(--ds-radius-sm);
    font-size: var(--ds-text-sm);
}

.fp-group {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-2);
    padding-block-start: var(--ds-space-3);
    border-block-start: 1px solid var(--ds-border-default);
}

.fp-row-3 {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--ds-space-2);
}

.fp-group-title {
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.fp-row-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--ds-space-3);
}

/* Number is short; the name gets the room. */
.fp-row-num {
    grid-template-columns: 88px minmax(0, 1fr);
}

.fp-detail .ds-input {
    min-height: 44px;
    width: 100%;
    box-sizing: border-box;
}

/* The steppers and rotate buttons do this job; the browser's own tiny arrows
   inside the box only crowd the number. */
.fp-detail input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
}

.fp-detail input[type="number"]::-webkit-inner-spin-button,
.fp-detail input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* "hidden" has to win over the display: flex these blocks carry, or a hidden
   list still takes its height and the panel scrolls past empty space. */
.fp-props-panel [hidden] {
    display: none !important;
}

/* Seats and rotation: the common change is one tap, typing still works. */
.fp-stepper {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) 44px;
    gap: var(--ds-space-2);
}

.fp-stepper .ds-input {
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.fp-step-btn {
    min-height: 44px;
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-sm);
    background: var(--ds-bg-surface);
    color: var(--ds-text-primary);
    font: inherit;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}

:where(.can-hover) .fp-step-btn:hover {
    background: var(--ds-bg-inset);
}

/* Shape as pictures, not a dropdown of words. One row; the chosen shape's
   name is under the table title, and each picture names itself on hover. */
.fp-shape-picker {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: var(--ds-space-2);
}

.fp-shape-opt {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 52px;
    padding: var(--ds-space-1) 2px;
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-md);
    background: var(--ds-bg-surface);
    color: var(--ds-text-secondary);
    font: inherit;
    font-size: var(--ds-text-xs);
    cursor: pointer;
}

:where(.can-hover) .fp-shape-opt:hover {
    border-color: var(--ds-primary);
}

.fp-shape-opt.is-active {
    border-color: var(--ds-primary);
    background: var(--ds-primary-tint);
    color: var(--ds-primary);
    box-shadow: inset 0 0 0 1px var(--ds-primary);
}

.fp-shape-opt.is-active .fp-palette-shape {
    border-color: var(--ds-primary);
}

.fp-align-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--ds-space-2);
}

.fp-chip-btn {
    min-height: 44px;
    padding: 0 var(--ds-space-2);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-sm);
    background: var(--ds-bg-surface);
    color: var(--ds-text-primary);
    font: inherit;
    font-size: var(--ds-text-sm);
    cursor: pointer;
}

:where(.can-hover) .fp-chip-btn:hover:not(:disabled) {
    border-color: var(--ds-primary);
    color: var(--ds-primary);
}

.fp-chip-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

/* What you can do to this table, at the end of it -- and pinned to the bottom
   of the panel, so on the 730px till, where the view is taller than the
   panel, Delete is still on screen while the fields above scroll. The
   negative bottom and matching padding cover the panel's own padding. */
.fp-detail-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--ds-space-2);
    padding-block: var(--ds-space-3) var(--ds-space-4);
    border-block-start: 1px solid var(--ds-border-default);
    position: sticky;
    bottom: calc(-1 * var(--ds-space-4));
    margin-block-end: calc(-1 * var(--ds-space-4));
    background: var(--ds-bg-surface);
    z-index: 1;
}

.fp-detail-actions .ds-btn {
    min-height: 44px;
}

/* One table: Select row, Duplicate, Delete on one line. */
.fp-detail-actions.is-single {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* List rows: number badge, name, seats. Taller, so they are real targets. */
.fp-table-row {
    gap: var(--ds-space-3);
    min-height: 48px;
}

.fp-table-row-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.fp-table-row-text .fp-table-row-name {
    color: var(--ds-text-primary);
    font-weight: var(--ds-fw-medium);
}

.fp-table-row-meta {
    font-size: var(--ds-text-xs);
    color: var(--ds-text-tertiary);
}

.fp-table-row.is-selected .fp-num-badge {
    background: var(--ds-primary);
    color: #FFFFFF;
}
