/* ============================================================
   UI PRIMITIVES — base classes for new code
   ============================================================
   Loaded after design-tokens.css and before the module files
   (module styles may override primitives when needed).
   Existing classes migrate to these gradually; new code should
   use .btn / .icon-btn / .field / .badge / .card directly.
   ============================================================ */

/* ── Buttons ─────────────────────────────────────────────────── */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font: inherit;
    font-weight: 600;
    font-size: var(--dc-text-md);
    padding: 8px 16px;
    border: 1.5px solid transparent;
    border-radius: var(--dc-radius-sm);
    cursor: pointer;
    transition: background var(--dc-transition), border-color var(--dc-transition), color var(--dc-transition);
    white-space: nowrap;
}
.btn:focus-visible { outline: none; box-shadow: var(--dc-focus-ring); }
.btn:disabled { opacity: .55; cursor: not-allowed; }

.btn--primary { background: var(--dc-c-accent); color: var(--dc-n-0); border-color: var(--dc-c-accent); }
.btn--primary:hover { background: var(--dc-c-accent-hover); border-color: var(--dc-c-accent-hover); }

.btn--success { background: var(--dc-c-success); color: var(--dc-n-0); border-color: var(--dc-c-success); }
.btn--success:hover { background: var(--dc-c-success-hover); border-color: var(--dc-c-success-hover); }

.btn--danger { background: var(--dc-c-error); color: var(--dc-n-0); border-color: var(--dc-c-error); }
.btn--danger:hover { background: var(--dc-c-error-hover); border-color: var(--dc-c-error-hover); }

.btn--ghost { background: rgba(0, 0, 0, 0.04); color: var(--dc-n-900); border-color: rgba(0, 0, 0, 0.12); }
.btn--ghost:hover { background: rgba(0, 0, 0, 0.08); }

.btn--sm { padding: 5px 12px; font-size: var(--dc-text-sm); }
.btn--pill { border-radius: 20px; }
.btn--block { width: 100%; }

/* ── Icon button (square ~30px with a glyph) ─────────────────── */

.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Square, and the same height as a button and a field beside it. The size is a
       custom property rather than two literals so a whole row of them can be retuned
       from the container that holds them — a container query cannot add a class, and
       --sm is not always the answer. The compact link card sets it to 28px
       (css/panel-links.css). */
    width: var(--icon-btn-size, var(--dc-control-h));
    height: var(--icon-btn-size, var(--dc-control-h));
    flex-shrink: 0;
    border-radius: var(--dc-radius-sm);
    /* background-color (not the shorthand) so icon variants keep their
       background-image on hover */
    background-color: rgba(0, 0, 0, 0.05);
    border: 1.5px solid rgba(0, 0, 0, 0.12);
    color: var(--dc-n-800);
    cursor: pointer;
    line-height: 1;
    padding: 0;
    transition: background-color var(--dc-transition), color var(--dc-transition), border-color var(--dc-transition);
}
.icon-btn:hover { background-color: rgba(0, 0, 0, 0.1); color: var(--dc-n-1000); }
.icon-btn:focus-visible { outline: none; box-shadow: var(--dc-focus-ring); }
.icon-btn--circle { border-radius: 50%; }
.icon-btn--danger:hover {
    background-color: rgba(231, 76, 60, 0.1);
    border-color: rgba(231, 76, 60, 0.4);
    color: var(--dc-c-error);
}

/* ── Typed icon buttons (app's own SVG icons, one look everywhere) ──
   Usage: <button class="icon-btn icon-btn--delete" title="Delete"></button>
   Add .icon-btn--sm for dense rows (tables, list items). */

/* Look: the app-native white chip (as used by link cards / zone buttons).
   The icon is drawn on ::before via mask + currentColor, so it is immune to
   global `button:hover { background: ... }` shorthand rules and RECOLORS on
   hover together with the border: settings and copy -> accent, delete -> red.
   Base icon color matches the SVGs' native #82655c. */
.icon-btn--settings,
.icon-btn--copy,
.icon-btn--delete {
    color: #82655c;
    background-color: var(--dc-n-0);
    border: 2px solid var(--dc-n-150);
    border-radius: var(--dc-radius-sm);
}
.icon-btn--settings::before,
.icon-btn--copy::before,
.icon-btn--delete::before {
    content: '';
    width: 20px;
    height: 20px;
    background-color: currentColor;
    -webkit-mask: center / contain no-repeat;
    mask: center / contain no-repeat;
}
.icon-btn--settings::before {
    -webkit-mask-image: url('../images/icon_settings.svg');
    mask-image: url('../images/icon_settings.svg');
}
.icon-btn--copy::before {
    -webkit-mask-image: url('../images/icon_copy.svg');
    mask-image: url('../images/icon_copy.svg');
}
.icon-btn--delete::before {
    -webkit-mask-image: url('../images/icon_delete.svg');
    mask-image: url('../images/icon_delete.svg');
}
.icon-btn--settings:hover,
.icon-btn--copy:hover {
    color: var(--dc-c-accent);
    background-color: #f0f8f6;
    border-color: var(--dc-c-accent);
}
.icon-btn--delete:hover {
    color: var(--dc-c-error);
    background-color: #fdf0ee;
    border-color: var(--dc-c-error);
}

.icon-btn--sm { --icon-btn-size: 22px; }
.icon-btn--sm.icon-btn--settings::before,
.icon-btn--sm.icon-btn--copy::before,
.icon-btn--sm.icon-btn--delete::before { width: 14px; height: 14px; }

/* There is no --close variant here, on purpose. The dialog close button is
   .modal-close-btn in css/modals.css - 26 elements wear it - and the --close declared
   here was worn by nothing at all. A primitive nobody puts on is not a primitive; it is
   a second answer, waiting to disagree with the first. Which it did: two more hand-made
   copies drifted into css/productSelector.css and one of them lost its hover colour, so
   the cross vanished under the pointer. See
   docs/completed/2026-09-07-modal-close-button.md.
   scripts/modal-consistency-check.mjs fails if a second one appears again. */

/* ── Tabs (underline style) ──────────────────────────────────── */

.tabs {
    display: flex;
    gap: 4px;
    border-bottom: 2px solid var(--dc-n-100);
}
.tab {
    padding: 8px 14px;
    border: none;
    background: none;
    font: inherit;
    font-size: var(--dc-text-md);
    font-weight: 600;
    color: var(--dc-n-500);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    transition: color var(--dc-transition-fast), border-color var(--dc-transition-fast);
}
.tab:hover { color: var(--dc-c-dark); }
.tab.active {
    color: var(--dc-c-accent);
    border-bottom-color: var(--dc-c-accent);
}
.tab:focus-visible { outline: none; box-shadow: var(--dc-focus-ring); }

/* ── Input fields ────────────────────────────────────────────── */

.field {
    font: inherit;
    font-size: var(--dc-text-md);
    padding: 8px 11px;
    background: var(--dc-field-bg);
    border: 1.5px solid var(--dc-field-border);
    border-radius: var(--dc-field-radius);
    color: var(--dc-field-text);
    outline: none;
    transition: border-color var(--dc-transition), box-shadow var(--dc-transition);
}
.field::placeholder { color: var(--dc-field-placeholder); }
.field:focus { border-color: var(--dc-field-border-focus); box-shadow: var(--dc-focus-ring); }
.field:disabled { background: var(--dc-n-25); color: var(--dc-n-500); }

/* ── Badges / pills ──────────────────────────────────────────── */

/* THE badge. Fifteen classes used to draw one, so this is built to cover all of
   them along three axes that can be combined freely:

     tone       what the colour means  — neutral (default), --accent, --info,
                --warning, --danger, --success
     emphasis   how loud it is         — soft (default), --solid, --outline
     shape      capsule (default) or --chip, a 4px corner for dense rows

   A tone sets three custom properties and nothing else; the emphasis modifiers
   decide which of the three to paint with. That way a tone is written once, and
   adding one is three values rather than three rules per emphasis.

   Not every badge in the product belongs here. A badge pinned to the corner of a
   card (.bom-qty-badge, .lp-card-badge) is this look plus a position, and the
   position belongs to the card. The panel-side badge (.lp-ep-panel-badge) keeps
   its own colours because they carry meaning: blue is the front, red the rear. */

.badge {
    /* neutral, and the fallback for every emphasis */
    --badge-soft: #eef1f3;
    --badge-ink:  #55606a;
    --badge-line: #c8d0d6;

    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: var(--dc-text-2xs);
    font-weight: 600;
    line-height: 1.4;
    padding: 2px 8px;
    border: 1px solid transparent;
    border-radius: 20px;
    white-space: nowrap;
    background: var(--badge-soft);
    color: var(--badge-ink);
}

/* ── Tone: three values, no painting ──────────────────────────── */
.badge--accent  { --badge-soft: var(--dc-c-accent-light); --badge-ink: #2a8068; --badge-line: #bcded4; }
.badge--info    { --badge-soft: #e8f4fd; --badge-ink: var(--dc-c-info);        --badge-line: #bcdcf2; }
.badge--warning { --badge-soft: #fdf3e8; --badge-ink: #c0770a;                 --badge-line: #f0d5b0; }
.badge--danger  { --badge-soft: #fdeceb; --badge-ink: var(--dc-c-error-hover); --badge-line: #f3c6c1; }
.badge--success { --badge-soft: #eafaf1; --badge-ink: var(--dc-c-success-hover); --badge-line: #bde5cd; }

/* ── Emphasis: painting only. After the tones, so these win. ───── */
.badge--solid   { background: var(--badge-ink); color: var(--dc-n-0); border-color: var(--badge-ink); }
.badge--outline { background: transparent; color: var(--badge-ink); border-color: var(--badge-line); }
/* Soft, but with the tone's hairline drawn. For a badge that has to hold its edge on a
   busy surface - a fibre tag among photographs, a chip on a report row. */
.badge--edged   { border-color: var(--badge-line); }

/* ── Shape and size ───────────────────────────────────────────── */
/* Padding matched to the link chips, which are far and away the most of them. */
.badge--chip { border-radius: var(--dc-radius-xs); padding: 2px 7px; }
.badge--chip img { display: block; }
/* One size up. Not in the first draft of this anatomy, which had a single size —
   the product then turned out to hold two: 10px for a label pinned to something
   (a fibre kind, a slot, a count) and 12px for a badge read on its own line (the
   project cost in the header, a role beside a name). Three of the families that
   moved in were the second kind, so the size is an axis after all. */
.badge--md { font-size: var(--dc-text-sm); padding: 3px 10px; }

/* ── Cards ───────────────────────────────────────────────────── */

.card {
    background: var(--dc-n-0);
    border: 1px solid var(--dc-modal-border);
    border-radius: var(--dc-radius-md);
    overflow: hidden;
}
.card--hover {
    transition: transform var(--dc-transition), box-shadow var(--dc-transition);
    cursor: pointer;
}
.card--hover:hover { transform: translateY(-3px); box-shadow: var(--dc-elev-md); }

/* ── Mini modal (small floating popover: hover/click info) ───────
   A lightweight reusable popover — not a native title tooltip. Show it
   via the showMiniModal(html, x, y) helper (js/utils.js). Compose the
   body with .mini-modal-title / .mini-modal-row. */

.mini-modal {
    position: fixed;
    /* Above any modal (incl. fullscreen zoom modals) — it's a floating popover */
    z-index: var(--dc-z-toast);
    background: var(--dc-modal-surface);
    color: var(--dc-c-dark);
    border: 1px solid var(--dc-modal-border);
    border-radius: var(--dc-radius-md);
    box-shadow: var(--dc-elev-md);
    padding: 8px 11px;
    font-size: var(--dc-text-sm);
    line-height: 1.4;
    max-width: 260px;
    pointer-events: none;
    opacity: 0;
    transform: translateY(3px);
    transition: opacity var(--dc-transition-fast), transform var(--dc-transition-fast);
}
.mini-modal--visible { opacity: 1; transform: translateY(0); }
.mini-modal-title {
    font-weight: 700;
    font-size: var(--dc-text-sm);
    margin-bottom: 2px;
    color: var(--dc-c-dark);
}
.mini-modal-row { color: var(--dc-c-muted); font-size: var(--dc-text-xs); }
.mini-modal-row strong { color: var(--dc-c-dark); font-weight: 600; }

/* ── Spinner (inline loading indicator) ──────────────────────── */

.spinner {
    display: inline-block;
    width: 16px;
    height: 16px;
    border: 2px solid rgba(0, 0, 0, 0.15);
    border-top-color: var(--dc-c-accent);
    border-radius: 50%;
    animation: dcSpin 0.7s linear infinite;
    vertical-align: middle;
}
.spinner--sm { width: 13px; height: 13px; }

/* ── Empty / placeholder state (centered muted text) ─────────── */

.empty-state {
    text-align: center;
    color: var(--dc-c-muted);
    font-size: var(--dc-text-md);
    line-height: 1.5;
    padding: 24px 12px;
}

/* ── Utilities ───────────────────────────────────────────────── */

.img-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--dc-img-placeholder-bg);
    color: var(--dc-img-placeholder-icon);
}

/* Slim scrollbar (same look as .panel-viz-modal .modal-body) */
.scroll-slim::-webkit-scrollbar { width: 8px; height: 8px; }
.scroll-slim::-webkit-scrollbar-track { background: transparent; }
.scroll-slim::-webkit-scrollbar-thumb { background: var(--dc-n-200); border-radius: 4px; }
.scroll-slim::-webkit-scrollbar-thumb:hover { background: var(--dc-n-400); }
