/* Settings page - page-scoped, --ds-* tokens only */

.settings-page {
    padding: 0;
    max-width: none;
}

.settings-shell {
    display: flex;
    align-items: flex-start;
    gap: var(--ds-space-5);
    min-height: 0;
    width: 100%;
}

/*
 * The rail scrolls inside itself instead of spilling out of its card.
 *
 * `design-system.css` sets `align-items: stretch` on `.settings-page >
 * .settings-shell`, so this rail is sized to the height of the CONTENT PANEL
 * beside it. With 15 nav entries the rail's own content is taller than a short
 * panel -- measured 728px of buttons in a 645px box -- and the default
 * `overflow: visible` neither clipped nor scrolled it. The surplus simply
 * spilled: the last entries rendered below the card's border, and on an
 * 802px-tall window "Data" landed at y=860, off-screen and unclickable. There
 * was no scrollbar because nothing was scrollable, and the settings page does
 * not scroll either, so those entries were unreachable. The 768px POS screens
 * this cafe runs make it worse.
 *
 * The stretch is deliberately left alone -- it is what gives the rail its
 * full-height card next to the panel. Only the overflow behaviour changes.
 * `max-height: 100%` is belt and braces for any layout where the stretch does
 * not apply; it resolves against the shell's definite height, which is exactly
 * the visible area.
 */
.settings-tab-rail {
    flex: 0 0 240px;
    position: sticky;
    top: var(--ds-space-4);
    max-height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-1);
    padding: var(--ds-space-3);
    background: var(--ds-bg-surface);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-lg);
}

.settings-rail-search {
    flex-shrink: 0;
    margin-block-end: var(--ds-space-2);
}

.settings-rail-search-input {
    width: 100%;
    min-height: 36px;
    font-size: var(--ds-text-sm);
}

.settings-rail-group {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-1);
    margin-block-end: var(--ds-space-2);
}

.settings-rail-group:last-child {
    margin-block-end: 0;
}

/* Section heading: an icon chip, the name, and a rule running to the edge, so
   each group reads as a group rather than as one more grey line in a list.
   The section holding the open tab lights up with it. */
.settings-rail-heading {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-semibold);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ds-text-secondary);
    padding: var(--ds-space-3) var(--ds-space-1) var(--ds-space-1);
    flex-shrink: 0;
}

.settings-rail-group:first-of-type .settings-rail-heading {
    padding-block-start: var(--ds-space-1);
}

.settings-rail-heading::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--ds-border-default);
}

.settings-rail-heading-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border-radius: var(--ds-radius-sm);
    background: var(--ds-bg-inset);
    color: var(--ds-text-secondary);
}

.settings-rail-group.has-active .settings-rail-heading {
    color: var(--ds-text-primary);
}

.settings-rail-group.has-active .settings-rail-heading-icon {
    background: var(--ds-primary-tint);
    color: var(--ds-primary);
}

/* A nav entry must never shrink to fit; the rail scrolls instead. Without
   this, flex would compress the buttons and clip their labels. */
.settings-tab-rail > * {
    flex-shrink: 0;
}

.settings-tab-strip {
    display: none;
    gap: var(--ds-space-1);
    overflow-x: auto;
    padding: var(--ds-space-2);
    margin-block-end: var(--ds-space-4);
    background: var(--ds-bg-surface);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-lg);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}

.settings-tab-btn {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    position: relative;
    width: 100%;
    min-height: var(--ds-touch-target);
    padding: var(--ds-space-2) var(--ds-space-3);
    border: 1px solid transparent;
    border-radius: var(--ds-radius-md);
    background: transparent;
    color: var(--ds-text-secondary);
    font-size: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    text-align: start;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--ds-motion-hover) var(--ds-ease-standard),
                color var(--ds-motion-hover) var(--ds-ease-standard);
}

.settings-tab-icon {
    display: inline-flex;
    flex-shrink: 0;
    color: var(--ds-text-tertiary);
}

/* Long names wrap to a second line rather than losing their end to an
   ellipsis ("Kitchen display thresholds" and the Arabic inventory label did,
   once the icon took its 24px). */
.settings-tab-rail .settings-tab-label {
    min-width: 0;
    white-space: normal;
    line-height: 1.25;
}

.settings-tab-btn:hover .settings-tab-icon {
    color: var(--ds-text-secondary);
}

.settings-tab-strip .settings-tab-btn {
    width: auto;
    flex: 0 0 auto;
}

.settings-tab-btn:hover {
    background: var(--ds-bg-inset);
    color: var(--ds-text-primary);
}

/* Active: tint, weight, and a bar on the leading edge -- the bordered pill it
   replaces read the same as a hovered row. */
.settings-tab-btn.is-active {
    background: var(--ds-primary-tint);
    color: var(--ds-primary);
    border-color: transparent;
    font-weight: var(--ds-fw-semibold);
}

.settings-tab-btn.is-active .settings-tab-icon {
    color: var(--ds-primary);
}

.settings-tab-rail .settings-tab-btn.is-active::before {
    content: '';
    position: absolute;
    inset-inline-start: 0;
    top: 8px;
    bottom: 8px;
    width: 3px;
    border-radius: 3px;
    background: var(--ds-primary);
}

.settings-main {
    flex: 1;
    min-width: 0;
}

.settings-panel-stack {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
}

.settings-section {
    margin-block-end: 0;
}

.settings-section-title {
    margin: 0 0 var(--ds-space-1) 0;
}

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

/* A note under one control, not under the whole section. Sits tight to the
   field above it so it reads as that field's footnote. */
.settings-field-hint {
    margin: var(--ds-space-1) 0 0 0;
    font-size: var(--ds-text-xs);
    line-height: 1.4;
    color: var(--ds-text-secondary);
}

.settings-form-row,
.settings-section .form-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--ds-space-3);
}

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

@media (min-width: 1024px) {
    .settings-form-row,
    .settings-section .form-row {
        grid-template-columns: 1fr 1fr;
    }

    .settings-form-row-3 {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (max-width: 640px) {
    .settings-form-row-3 {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 900px) {
    .settings-shell {
        flex-direction: column;
    }

    .settings-tab-rail {
        display: none;
    }

    .settings-tab-strip {
        display: flex;
    }
}

.settings-logo-row {
    display: flex;
    align-items: center;
    gap: var(--ds-space-3);
    flex-wrap: wrap;
}

.settings-logo-preview {
    width: 64px;
    height: 64px;
    object-fit: contain;
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-md);
    background: var(--ds-bg-inset);
}

.settings-cat-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-3);
    flex-wrap: wrap;
    margin-block-end: var(--ds-space-3);
}

.settings-cat-hint {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
    margin: 0 0 var(--ds-space-3) 0;
}

.settings-cat-swatch {
    width: 36px;
    height: 36px;
    border-radius: var(--ds-radius-sm);
    border: 1px solid var(--ds-border-default);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--ds-text-sm);
    font-weight: 600;
    color: var(--ds-text-on-accent);
}

.settings-cat-cover {
    width: 36px;
    height: 36px;
    object-fit: cover;
    border-radius: var(--ds-radius-sm);
    border: 1px solid var(--ds-border-default);
}

.settings-cat-cover-preview {
    width: 72px;
    height: 72px;
    object-fit: cover;
    border-radius: var(--ds-radius-md);
    border: 1px solid var(--ds-border-default);
    background: var(--ds-bg-inset);
}

.settings-cat-cover-preview.is-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--ds-text-xs);
    color: var(--ds-text-tertiary);
    text-align: center;
    padding: var(--ds-space-2);
}

.settings-cat-cover-row {
    display: flex;
    gap: var(--ds-space-3);
    align-items: center;
}

.settings-cat-nested td:nth-child(2) {
    padding-inline-start: var(--ds-space-5);
}

.settings-cat-nest-mark {
    color: var(--ds-text-tertiary);
    margin-inline-end: var(--ds-space-1);
}

.settings-cat-parent-hint {
    display: block;
    font-size: var(--ds-text-xs);
    color: var(--ds-text-tertiary);
}

.settings-cat-drag {
    width: 28px;
    text-align: center;
    color: var(--ds-text-tertiary);
    cursor: grab;
    user-select: none;
    font-size: 1.1rem;
    line-height: 1;
}

.settings-cat-row.dragging {
    opacity: 0.45;
}

.settings-cat-row.drop-target {
    box-shadow: inset 0 2px 0 var(--ds-primary);
}

.settings-cat-color-input {
    width: 36px;
    height: 36px;
    padding: 2px;
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-sm);
    cursor: pointer;
    background: transparent;
}

.settings-cat-size-select {
    min-width: 4.5rem;
    padding: var(--ds-space-1) var(--ds-space-2);
    font-size: var(--ds-text-sm);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-sm);
    background: var(--ds-surface);
}

.settings-cat-cover-btn {
    appearance: none;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    border-radius: var(--ds-radius-sm);
}

.settings-cat-cover-btn:focus-visible {
    outline: 2px solid var(--ds-primary);
    outline-offset: 2px;
}

.settings-data-actions {
    display: flex;
    gap: var(--ds-space-2);
    flex-wrap: wrap;
}

.settings-day-chips {
    display: flex;
    gap: var(--ds-space-2);
    flex-wrap: wrap;
    margin-block-start: var(--ds-space-1);
}

.settings-day-chip {
    display: flex;
    align-items: center;
    gap: var(--ds-space-1);
    cursor: pointer;
    font-size: var(--ds-text-sm);
    color: var(--ds-text-primary);
}

.settings-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-lg);
}

/*
 * These labels carry BOTH `settings-toggle-row` and `ds-field`, and `ds-field`
 * sets `flex-direction: column`. Nothing here overrode it, so the row inherited
 * a column direction -- at which point `align-items: center` stopped meaning
 * "line the switch up with its label" and started meaning "centre everything
 * horizontally". Every toggle in Settings rendered as a switch floating in the
 * middle of the card with its label stranded underneath.
 *
 * Stating the direction explicitly is the fix: it wins over `.ds-field`
 * regardless of which stylesheet loads last, so the row cannot silently flip
 * again if the load order changes.
 */
.settings-toggle-row {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: var(--ds-space-2);
    cursor: pointer;
}

/* A module whose server side is not ready. Shown rather than hidden, so the
   owner can see it is coming and is not left wondering where it went -- but
   not clickable, because the switch cannot open it. */
.settings-toggle-row.is-unavailable {
    cursor: not-allowed;
    opacity: 0.6;
}

.settings-toggle-note {
    font-size: var(--ds-text-xs);
    color: var(--ds-text-tertiary);
    border: 1px solid var(--ds-border);
    border-radius: var(--ds-radius-sm);
    padding: 0 var(--ds-space-2);
    margin-inline-start: var(--ds-space-2);
    white-space: nowrap;
}

/* The switch keeps its size; only the label takes up the slack. */
.settings-toggle-row > .ds-toggle {
    flex: 0 0 auto;
}

.settings-toggle-row .ds-label {
    margin: 0;
    font-weight: var(--ds-fw-normal);
}

.settings-method-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: var(--ds-space-2);
}

.settings-method-item {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    padding: var(--ds-space-2) var(--ds-space-3);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-md);
    background: var(--ds-bg-inset);
    cursor: pointer;
}

.settings-hours-grid {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-2);
}

.settings-hours-row {
    display: grid;
    grid-template-columns: 80px 1fr 1fr auto;
    gap: var(--ds-space-2);
    align-items: center;
}

@media (max-width: 640px) {
    .settings-hours-row {
        grid-template-columns: 1fr;
    }
}

.settings-kds-row {
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    gap: var(--ds-space-2);
    align-items: center;
    padding-block: var(--ds-space-2);
    border-block-start: 1px solid var(--ds-border-default);
}

.settings-kds-row:first-child {
    border-block-start: none;
    padding-block-start: 0;
}

.settings-readonly-note {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
    padding: var(--ds-space-3);
    background: var(--ds-bg-inset);
    border-radius: var(--ds-radius-md);
    border: 1px solid var(--ds-border-default);
}

.settings-link-row {
    margin-block-start: var(--ds-space-3);
}

/* ── Receipt preview (Settings → Receipt & Printing) ───────────────────────
 *
 * Two receipts side by side: what is printing today, and what Save would
 * print. Drawn with the real .receipt-* rules from print.css, which is loaded
 * for all media, so this is the receipt rather than a drawing of one.
 *
 * True size, not scaled. The whole question is whether a header line fits on
 * the roll, and a scaled preview answers a different question.
 *
 * Absolute #000/#fff in this block match print.css thermal contrast; do not
 * map them to --ds-canvas / --ds-text-primary.
 */
.receipt-preview {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ds-space-4);
    margin-block: var(--ds-space-4);
}

.receipt-preview-col {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-2);
    min-width: 0;
}

.receipt-preview-label {
    font-size: var(--ds-text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ds-text-secondary);
}

/* The paper. A mid-grey behind it so white-on-white does not read as a void,
   the way a receipt looks against a counter. */
.receipt-preview-paper {
    padding: 10px;
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface-alt);
    border: 1px solid var(--ds-border-default);
    width: max-content;
    max-width: 100%;
    overflow-x: auto;
}

/*
 * #receipt is the element that actually prints, and there is only one of it.
 * The preview borrows its rules by repeating the two that matter -- width and
 * the type -- rather than by cloning the id, which would give the document two
 * elements answering to #receipt and break the print measurement.
 */
.receipt-preview-receipt {
    width: var(--receipt-w, 80mm);
    box-sizing: border-box;
    background: #fff;
    color: #000;
    font-family: 'Courier New', Courier, monospace;
    font-size: 13px;
    font-weight: bold;
    border: 1px solid #000;
    padding: 2.5mm;
    --r-gap: 2.5mm;
    --r-row: 1.25mm;
    --r-rule: 1px solid #000;
    --r-rule-strong: 2px solid #000;
}

/* ══════════════════════════════════════════════════════════════════════════
   Pay Bill layout: pick a shape by looking at it

   This was a <select> holding the words "Split" and "Compact". The choice is
   entirely about the shape of a modal, which is the one thing a dropdown
   cannot show -- so each option carries a wireframe of what it produces,
   drawn in CSS rather than shipped as an image so it cannot go stale
   silently.
   ═════════════════════════════════════════════════════════════════════════ */
.settings-layout-choice {
    border: 0;
    padding: 0;
    margin: 0;
    min-width: 0;   /* a fieldset defaults to min-content; without this it
                       refuses to shrink and pushes the card wider */
}

.settings-layout-choice > .ds-label {
    padding: 0;
    margin-block-end: var(--ds-space-2);
}

.settings-layout-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--ds-space-3);
}

.settings-layout-card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: var(--ds-space-3);
    padding: var(--ds-space-3);
    border: 2px solid var(--ds-border-default);
    border-radius: var(--ds-radius-lg);
    background: var(--ds-surface);
    cursor: pointer;
}

/* The whole card is the target, so the radio itself is redundant -- but it
   stays in the DOM and stays focusable, because it is what a keyboard and a
   screen reader use to work the group. */
.settings-layout-card input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.settings-layout-card:hover { border-color: var(--ds-border-strong, var(--ds-border-default)); }

.settings-layout-card:has(input:checked) {
    border-color: var(--ds-primary);
    background: var(--ds-primary-tint, var(--ds-surface));
}

/* Focus lands on the hidden radio, so the ring has to be drawn by the card. */
.settings-layout-card:has(input:focus-visible) {
    outline: 2px solid var(--ds-primary);
    outline-offset: 2px;
}

.settings-layout-card-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.settings-layout-card-name {
    font-size: var(--ds-text-base);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-primary);
}

.settings-layout-card-desc {
    font-size: var(--ds-text-xs);
    line-height: 1.4;
    color: var(--ds-text-secondary);
}

/* ── The wireframe ─────────────────────────────────────────────────────── */
/*
 * The drawing is a SCREEN with a MODAL on it, not just a modal. That is what
 * makes the two options tell themselves apart: the first pass drew only the
 * inside of the modal and the compact one came out looking like the split
 * one's right-hand pane, which is the single thing a person picking between
 * them must not have to squint at. Drawn this way the difference is the
 * silhouette -- wide and halved, or narrow and stacked -- and it reads before
 * the label does.
 */
.settings-layout-preview {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 120px;
    height: 76px;
    flex-shrink: 0;
    padding: 6px;
    border-radius: 6px;
    border: 1px solid var(--ds-border-default);
    background: var(--ds-bg-inset, var(--ds-surface-alt));
}

.settings-layout-preview-modal {
    display: flex;
    flex-direction: column;
    gap: 4px;
    height: 100%;
    padding: 5px;
    border-radius: 4px;
    border: 1px solid var(--ds-border-default);
    background: var(--ds-surface);
}

.settings-layout-preview.is-split .settings-layout-preview-modal { width: 100%; }

/* Not a stylistic choice: the compact modal really is narrower, 560px against
   980, and that is most of what picking it does to the screen. */
.settings-layout-preview.is-compact .settings-layout-preview-modal { width: 56%; }

.settings-layout-preview-body {
    display: flex;
    gap: 5px;
    flex: 1;
    min-height: 0;
}

.settings-layout-preview-pane {
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: 1;
    min-width: 0;
}

/* The rule between the panes is the one the modal draws. */
.settings-layout-preview.is-split .settings-layout-preview-pane + .settings-layout-preview-pane {
    border-inline-start: 1px solid var(--ds-border-default);
    padding-inline-start: 5px;
}

/* Only the leaves are inked, so the structural elements above need no reset. */
.settings-layout-preview-title,
.settings-layout-preview-row,
.settings-layout-preview-sum,
.settings-layout-preview-input,
.settings-layout-preview-foot,
.settings-layout-preview-tiles > span {
    background: var(--ds-text-tertiary);
    border-radius: 1px;
}

.settings-layout-preview-title { height: 4px; width: 50%; }
.settings-layout-preview-row { height: 3px; }

/* Heavier and darker: it is the total, and it is what makes three grey bars
   read as a bill. */
.settings-layout-preview-sum {
    height: 5px;
    margin-block-start: auto;
    background: var(--ds-text-secondary);
}

.settings-layout-preview-tiles {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3px;
}

.settings-layout-preview-tiles > span { height: 7px; }

.settings-layout-preview-input { height: 9px; }

/* The Confirm button, bottom right, where it is in the modal. */
.settings-layout-preview-foot {
    height: 5px;
    width: 38%;
    align-self: flex-end;
    background: var(--ds-primary);
}

/* ================================================================
   APPEARANCE -- accent colour picker
   ================================================================ */

/* auto-fill, not fixed columns: the till is 1520 wide and a phone is not,
   and eight swatches on one cramped row are eight things nobody can hit. */
.settings-theme-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
    gap: var(--ds-space-3);
    margin-block-end: var(--ds-space-5);
}

.settings-theme-swatch {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ds-space-2);
    padding: var(--ds-space-3);
    min-height: var(--ds-touch-target);
    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: var(--ds-text-sm);
    font-weight: var(--ds-fw-medium);
    cursor: pointer;
    transition: border-color var(--ds-transition-fast), box-shadow var(--ds-transition-fast);
}

.settings-theme-swatch:hover:not(:disabled) {
    border-color: var(--ds-border-strong);
}

.settings-theme-swatch:disabled {
    cursor: default;
    opacity: 0.6;
}

/* The ring is drawn in the swatch's OWN colour, not the current accent.
   Using --ds-primary here would mean the selected swatch changed colour as
   you clicked around, which is the one element that has to hold still. */
.settings-theme-swatch.is-active {
    border-color: var(--sw-accent);
    box-shadow: 0 0 0 2px var(--sw-accent) inset;
}

/* Two bands: the accent, and the sidebar shade derived from it. Half the
   screen is sidebar, so a preview that only showed the button colour would
   be showing the smaller half of the decision. */
.settings-theme-swatch-chip {
    width: 100%;
    height: 34px;
    border-radius: var(--ds-radius-sm);
    background: linear-gradient(120deg, var(--sw-sidebar) 0 42%, var(--sw-accent) 42% 100%);
    box-shadow: inset 0 0 0 1px rgba(30, 27, 57, 0.08);
}

.settings-theme-swatch-label {
    line-height: 1;
}

/* Packed left, not stretched: a 1fr column turned the six-character hex box
   into a 760px input on the till, which reads as somewhere to write a
   sentence. justify-content:start is what stops the grid filling the card. */
.settings-theme-custom {
    grid-template-columns: 150px 190px;
    justify-content: start;
    align-items: end;
    column-gap: var(--ds-space-4);
    margin-block-end: var(--ds-space-5);
}

@media (max-width: 720px) {
    .settings-theme-custom {
        grid-template-columns: 1fr;
    }
}

/* ---- The live preview -------------------------------------------------
   A working miniature of the app: sidebar rail, topbar, category tabs, a
   product grid and an order panel with a Pay button. Every colour in it comes
   from a --ds-* token, so Theme.apply() repaints it along with the real
   interface and there is nothing here to keep in sync by hand.
   ----------------------------------------------------------------------- */
.settings-theme-preview {
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-md);
    overflow: hidden;
    margin-block-end: var(--ds-space-5);
}

/* The miniature sits ON a surface rather than filling the card.
   Left to stretch to the card's full 1120px it was 1120x168 -- an aspect
   nothing has ever been -- and the three "product tiles" came out 340px wide,
   which reads as three empty panels rather than a POS grid. Centred at a
   till-ish 16:9 it reads as a small screenshot of the shop. */
.settings-theme-stage {
    display: flex;
    justify-content: center;
    padding: var(--ds-space-4);
    background: var(--ds-bg-inset);
}

.settings-mini {
    display: flex;
    width: min(100%, 480px);
    height: 270px;
    border-radius: var(--ds-radius-sm);
    overflow: hidden;
    border: 1px solid var(--ds-border-default);
    box-shadow: var(--ds-shadow-card);
    background: var(--ds-bg-canvas);
    /* Nothing in here is interactive; it is a picture made of divs. Without
       this, dragging across it selects the fake product names. */
    user-select: none;
}

.settings-mini-rail {
    flex: 0 0 38px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    padding: 8px 0;
    background: var(--ds-sidebar-bg);
}

.settings-mini-logo {
    width: 20px;
    height: 20px;
    object-fit: contain;
    border-radius: 5px;
    margin-block-end: 3px;
    background: rgba(255, 255, 255, 0.16);
}

.settings-mini-logo.is-mark {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 9px;
    font-weight: var(--ds-fw-bold);
    color: var(--ds-text-on-accent);
}

/* A resting nav item is a translucent bar on the sidebar wash; the active one
   is the white pill with an accent glyph, which is the single most
   accent-dependent element in the real chrome. */
.settings-mini-nav {
    width: 16px;
    height: 16px;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.22);
}

/* The active pill: white, with the accent showing through as the glyph. This
   is the one element in the real sidebar that INVERTS the accent -- accent on
   white rather than white on accent -- so it is the first thing to look wrong
   if someone picks a very pale colour. */
.settings-mini-nav.is-active {
    width: 22px;
    background: var(--ds-sidebar-pill);
    box-shadow: inset 0 0 0 4px var(--ds-sidebar-fg-active);
}

.settings-mini-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.settings-mini-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-2);
    padding: 6px 10px;
    background: var(--ds-bg-surface);
    border-block-end: 1px solid var(--ds-border-default);
}

.settings-mini-shop {
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-semibold);
    color: var(--ds-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.settings-mini-avatar {
    flex: none;
    width: 18px;
    height: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-primary-tint);
    color: var(--ds-primary);
    font-size: 8px;
    font-weight: var(--ds-fw-bold);
}

.settings-mini-work {
    flex: 1;
    min-height: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 92px;
    gap: 8px;
    padding: 8px;
}

.settings-mini-left {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.settings-mini-tabs {
    display: flex;
    gap: 4px;
}

.settings-mini-tab {
    padding: 3px 7px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-bg-surface);
    border: 1px solid var(--ds-border-default);
    font-size: 8px;
    font-weight: var(--ds-fw-medium);
    color: var(--ds-text-secondary);
}

/* Tint background with the full accent as text: the one place the 92% tint
   and the accent appear together, and the pair that fails first on a pale
   custom colour. */
.settings-mini-tab.is-active {
    background: var(--ds-primary-tint);
    border-color: var(--ds-primary);
    color: var(--ds-primary);
}

.settings-mini-grid {
    flex: 1;
    min-height: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 1fr;
    gap: 5px;
}

/* A tile is a picture with a name under it, so the miniature shows the shape
   of a product tile and not just a rounded rectangle. The ::before is the
   photo well; the label sits under it, as it does on the real grid. */
.settings-mini-tile {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 4px;
    border-radius: 6px;
    background: var(--ds-bg-surface);
    border: 1px solid var(--ds-border-default);
    font-size: 7px;
    line-height: 1;
    color: var(--ds-text-secondary);
    overflow: hidden;
}

.settings-mini-tile::before {
    content: '';
    flex: 1;
    border-radius: 3px;
    background: var(--ds-bg-inset);
}

.settings-mini-order {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 7px;
    border-radius: 8px;
    background: var(--ds-bg-surface);
    border: 1px solid var(--ds-border-default);
}

.settings-mini-line,
.settings-mini-total {
    display: flex;
    justify-content: space-between;
    gap: 4px;
    font-size: 7px;
    color: var(--ds-text-secondary);
}

.settings-mini-line em,
.settings-mini-total em { font-style: normal; }

.settings-mini-total {
    margin-block-start: auto;
    padding-block-start: 4px;
    border-block-start: 1px solid var(--ds-border-default);
    font-size: 8px;
    font-weight: var(--ds-fw-bold);
    color: var(--ds-text-primary);
}

/* The real Pay button, including the label colour Theme derived from the
   accent -- which is the whole reason to show a filled button at all. */
.settings-mini-pay {
    margin-block-start: 4px;
    padding: 5px 0;
    border-radius: 6px;
    background: var(--ds-primary);
    color: var(--ds-text-on-accent);
    font-size: 8px;
    font-weight: var(--ds-fw-bold);
    text-align: center;
}

/* ---- Readout: the status chips and the facts ---- */
.settings-theme-readout {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-3);
    flex-wrap: wrap;
    padding: var(--ds-space-3);
    background: var(--ds-bg-inset);
    border-block-start: 1px solid var(--ds-border-default);
}

.settings-mini-chips {
    display: flex;
    gap: var(--ds-space-2);
    flex-wrap: wrap;
}

/* Deliberately NOT accent-coloured. These are the three table states, shown
   next to the accent so a collision between the brand colour and a status is
   visible while there is still a Cancel button on screen. */
.settings-mini-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px var(--ds-space-2);
    border-radius: var(--ds-radius-pill);
    font-size: var(--ds-text-xs);
    font-weight: var(--ds-fw-semibold);
}

.settings-mini-chip::before {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: var(--ds-radius-pill);
    background: currentColor;
}

.settings-mini-chip.is-free { background: var(--ds-success-tint); color: var(--ds-success); }
.settings-mini-chip.is-open { background: var(--ds-warning-tint); color: var(--ds-warning); }
.settings-mini-chip.is-bill { background: var(--ds-danger-tint); color: var(--ds-danger); }

/* The colliding chip gets an accent ring, so the comparison is literally
   side by side on one element rather than left as an exercise. */
.settings-mini-chip.is-clashing {
    box-shadow: 0 0 0 2px var(--ds-primary);
}

.settings-theme-facts {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    font-family: var(--ds-font-mono);
    font-size: var(--ds-text-xs);
    color: var(--ds-text-secondary);
    font-variant-numeric: tabular-nums;
}

.settings-theme-clash {
    margin: 0;
    padding: var(--ds-space-3);
    background: var(--ds-warning-tint);
    border-block-start: 1px solid var(--ds-border-default);
    font-size: var(--ds-text-xs);
    line-height: 1.45;
    color: var(--ds-text-primary);
}

/* A corner flag on a preset that sits on a status colour. Small: it is a
   note, not a rejection -- these are all still shippable brand colours. */
.settings-theme-swatch-chip {
    position: relative;
}

.settings-theme-swatch-flag {
    position: absolute;
    inset-block-start: 4px;
    inset-inline-end: 4px;
    width: 8px;
    height: 8px;
    border-radius: var(--ds-radius-pill);
    background: var(--ds-surface);
    box-shadow: 0 0 0 2px rgba(30, 27, 57, 0.35);
}

.settings-theme-actions {
    display: flex;
    gap: var(--ds-space-2);
    flex-wrap: wrap;
}

/* Sticky save bar when a tracked card is dirty (NavGuard partner) */
.settings-save-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-3);
    flex-wrap: wrap;
    padding: var(--ds-space-3) var(--ds-space-5);
    padding-bottom: calc(var(--ds-space-3) + env(safe-area-inset-bottom, 0px));
    background: var(--ds-bg-surface);
    border-top: 1px solid var(--ds-border-default);
    box-shadow: 0 -4px 20px rgba(20, 20, 40, 0.08);
}

.settings-save-bar[hidden] {
    display: none !important;
}

.settings-save-bar-text {
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
    flex: 1;
    min-width: 0;
}

.settings-save-bar-actions {
    display: flex;
    gap: var(--ds-space-2);
    flex-shrink: 0;
}

body.settings-has-save-bar .settings-page {
    padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
}

/* Wave 4 T-N: repeated inline styles lifted from settings.js */
.settings-mt-4 { margin-top: var(--ds-space-4); }
.settings-mbs-4 { margin-block-start: var(--ds-space-4); }
.settings-mbs-3 { margin-block-start: var(--ds-space-3); }
.settings-m-0 { margin: 0; }
.settings-swatch-btn {
    min-height: 44px;
    padding: 4px;
}
.settings-align-end { align-self: flex-end; }

/* ================================================================
   READABLE SETTINGS (2026-09 design pass)

   Every field stretched to the panel: the receipt header textarea and the
   business profile inputs measured 1457px wide at 2048x1114, and the receipt
   preview began 758px down, below every control that changes it. Fields,
   rows and toggles now sit in a form-width column; tables, method grids and
   swatches keep the panel width.
   ================================================================ */

.settings-panel-stack {
    container-type: inline-size;
    container-name: settings-panel;
}

.settings-page .ds-field,
.settings-page .settings-form-row {
    max-width: 720px;
}

.settings-page .settings-form-row-3 {
    max-width: 960px;
}

.settings-page .settings-section-desc,
.settings-page .settings-field-hint {
    max-width: 72ch;
}

/* A run of switches reads as one list, each row a full touch target. */
.settings-page .settings-toggle-row {
    min-height: 44px;
    padding-block: var(--ds-space-1);
}

.settings-page .settings-toggle-row + .settings-toggle-row {
    border-top: 1px solid var(--ds-border);
}

/* Receipt & Printing: form beside its live preview when there is room. */
.settings-receipt-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--ds-space-5);
    align-items: start;
}

.settings-receipt-form {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-3);
    min-width: 0;
}

.settings-receipt-save {
    align-self: flex-start;
    margin-block-start: var(--ds-space-2);
}

@container settings-panel (min-width: 1240px) {
    .settings-receipt-layout {
        grid-template-columns: minmax(0, 640px) minmax(0, 1fr);
    }

    .settings-receipt-layout > .receipt-preview {
        position: sticky;
        top: var(--ds-space-4);
        margin-block: 0;
    }
}

/* Kitchen printing setup card (Settings -> Kitchen). */
.print-setup-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-3);
    margin-block-end: var(--ds-space-2);
}

.print-setup-step {
    padding-block: var(--ds-space-4);
    border-block-start: 1px solid var(--ds-border-default);
}

.print-setup-step-title {
    margin-block: 0 var(--ds-space-2);
}

.print-setup-agents {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-2);
    margin-block-start: var(--ds-space-3);
}

.print-setup-agent {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ds-space-2);
}

.print-setup-agent-name {
    font-weight: var(--ds-fw-medium);
}

.print-setup-station {
    max-width: 260px;
}

.print-setup-cats {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ds-space-2);
}

.print-setup-cat {
    display: inline-flex;
    align-items: center;
    gap: var(--ds-space-2);
    min-height: 44px;
    padding-inline: var(--ds-space-3);
    border: 1px solid var(--ds-border-default);
    border-radius: var(--ds-radius-md);
    background: var(--ds-surface);
    cursor: pointer;
}

.print-setup-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ds-space-3);
    padding-block-start: var(--ds-space-4);
    border-block-start: 1px solid var(--ds-border-default);
}

.print-setup-queue {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ds-space-3);
    margin-block-start: var(--ds-space-3);
    font-size: var(--ds-text-sm);
    color: var(--ds-text-secondary);
}

.print-setup-failed {
    color: var(--ds-danger);
    font-weight: var(--ds-fw-medium);
}

.print-setup-error {
    flex-basis: 100%;
    margin: 0;
    overflow-wrap: anywhere;
}

/* The network-printer fields hide while a USB printer is picked; the row's own
   display: grid would otherwise override the hidden attribute. */
.print-setup .settings-form-row[hidden] {
    display: none;
}
