/* ── TrunklyPlan ── assets/css/styles.css ───────────────────────────────
 *
 * Plugin-local stylesheet. Holds:
 *   1. Plugin-specific component classes (canvas wrapper, element rows,
 *      cut-plan bars, BOM, corner badges) — original content
 *   2. `tl-*` utility classes used in lieu of repeated inline styles
 *      across index.php / catalogue.php / statistics.php / editor-*.js
 *
 * Naming: every plugin-local utility is prefixed `tl-` (trunking layout)
 * so it can't collide with Bootstrap or future shared classes.
 * ───────────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════
 * CANVAS + ELEMENT LIST
 * ═══════════════════════════════════════════════════════════════════════ */

#canvas-wrapper {
    background: linear-gradient(160deg, var(--app-bg-1) 0%, var(--app-bg-2) 100%);
    border-radius: 0 0 var(--app-radius-md) var(--app-radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 300px;
    overflow: hidden;
}

/* On a wide (side-by-side) layout give the canvas a stable, viewport-based
   height so it no longer stretches to match the elements sidebar. Without this
   the canvas card grew every time an element was added (the list pushed the
   column taller) and the drawing re-centred, making the panel appear to jump.
   Now the canvas keeps a fixed height and the elements list scrolls on its own. */
@media (min-width: 992px) {
    #canvas-wrapper {
        height: min(78vh, 820px);
    }
}

/* The <canvas> element itself */
.tl-canvas {
    display: block;
    cursor: grab;
    max-width: 100%;
}

.element-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.75rem;
    border-bottom: 1px solid var(--app-border);
    cursor: pointer;
    transition: background 0.12s;
}
.element-row:last-child  { border-bottom: none; }
.element-row:hover       { background: var(--app-panel-2); }
.element-row.is-selected { background: var(--app-tint); border-left: 3px solid var(--app-primary); }

.element-swatch {
    width: 10px;
    height: 10px;
    border-radius: 2px;
    flex-shrink: 0;
}

.element-label {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--app-text);
    min-width: 2.5rem;
}

.element-meta {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    color: var(--app-text-muted);
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.element-actions {
    display: flex;
    gap: 0.2rem;
    flex-shrink: 0;
}

/* Elements list scrollable container */
.tl-elements-scroll {
    max-height: 360px;
    overflow-y: auto;
}

/* ═══════════════════════════════════════════════════════════════════════
 * CUTTING PLAN
 * ═══════════════════════════════════════════════════════════════════════ */

.cut-plan-section { margin-bottom: 1.5rem; }

.cut-plan-title {
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--app-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.stick-row { margin-bottom: 0.5rem; }

.stick-label {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    color: var(--app-text-muted);
    margin-bottom: 0.2rem;
}

.stick-bar {
    display: flex;
    height: 28px;
    border-radius: var(--app-radius-sm);
    overflow: hidden;
    border: 1px solid var(--app-border);
}

.stick-segment {
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-mono);
    font-size: 0.62rem;
    font-weight: 600;
    color: rgba(255,255,255,0.9);
    overflow: hidden;
    white-space: nowrap;
    padding: 0 3px;
    border-right: 1px solid rgba(0,0,0,0.3);
    cursor: default;
    transition: filter 0.1s;
}
.stick-segment:hover           { filter: brightness(1.2); }
.stick-segment:last-child      { border-right: none; }
.stick-segment.is-waste {
    background: var(--app-panel-2) !important;
    color: var(--app-text-faint);
    font-weight: 400;
}

.stick-info {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    color: var(--app-text-faint);
    margin-top: 0.15rem;
}

/* Optimizer summary stats */
.optim-stats {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}
.optim-stat-item {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}
.optim-stat-label {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--app-text-muted);
}
.optim-stat-value {
    font-family: var(--font-mono);
    font-size: 1rem;
    font-weight: 700;
    color: var(--app-text);
}

/* BOM table */
.bom-table th { font-size: 0.72rem; }
.bom-table td { font-family: var(--font-mono); font-size: 0.8rem; }

/* Misc */
.hole-badge {
    font-size: 0.6rem;
    padding: 0.1rem 0.35rem;
}

.corner-badge {
    font-size: 0.6rem;
    padding: 0.1rem 0.3rem;
    border-radius: 3px;
}
.corner-mitre { background: rgba(245,158,11,0.15); color: #f59e0b; }
.corner-open  { background: rgba(34,211,238,0.12); color: #22d3ee; }

[data-bs-toggle="tooltip"] { cursor: help; }

.hole-detail-row {
    font-family: var(--font-mono);
    font-size: 0.72rem;
}

/* ═══════════════════════════════════════════════════════════════════════
 * UTILITY CLASSES
 * ═══════════════════════════════════════════════════════════════════════
 *
 * These replace the repeated inline styles that previously dotted the
 * three PHP pages and the editor JS modules. Keep this section short:
 * if a one-off needs styling, prefer a Bootstrap utility before adding
 * a new tl-* class.
 */

/* Typography */
.tl-mono    { font-family: var(--font-mono); }
.tl-mono-sm { font-family: var(--font-mono); font-size: 0.78rem; }
.tl-mono-xs { font-family: var(--font-mono); font-size: 0.7rem; }

/* Tabular figures. --font-mono resolves to the Unex brand face (Helvetica
   Neue LT Std), which is proportional, so digits in the BOM, cut lists and
   coordinate/zoom badges did not line up column-to-column. Forcing
   tabular-nums gives every digit the same advance width without changing the
   typeface, so numeric columns align. Harmless where a mono context holds no
   digits. */
.font-mono, .tl-mono, .tl-mono-sm, .tl-mono-xs,
.bom-table td, .hole-detail-row, .tl-zoom-badge {
    font-variant-numeric: tabular-nums;
}

.tl-text-xxs { font-size: 0.6rem; }
.tl-text-xs  { font-size: 0.7rem; }
.tl-text-sm  { font-size: 0.78rem; }
.tl-text-md  { font-size: 0.8rem; }

/* Coord display badge in canvas card header */
.font-mono { font-family: var(--font-mono); }

/* Zoom-level badge — fixed min-width so it doesn't collapse when value shrinks */
.tl-zoom-badge {
    font-family: var(--font-mono);
    font-size: 0.68rem;
    min-width: 2.8rem;
}

/* Layout / overflow helpers */
.tl-overflow-visible { overflow: visible; }     /* card containing a dropdown */
.tl-w-auto           { width: auto; }            /* form-select that needs to shrink */
.tl-cursor-pointer   { cursor: pointer; }        /* on <label> wrappers acting as buttons */

/* Chart canvases — height caps prevent Chart.js from growing unbounded */
.tl-chart-sm { max-height: 180px; }
.tl-chart-md { max-height: 200px; }

/* Table column-width hints */
.tl-th-narrow { min-width: 70px; }
.tl-th-wide   { min-width: 120px; }

/* Filter dropdown that holds the size checkboxes */
.tl-size-dropdown-menu {
    min-width: 220px;
    max-height: 260px;
    overflow-y: auto;
}

/* Trunking Size dropdown trigger — match the sibling form-select-sm controls
   (rectangular 8px radius, normal weight, select-like height) instead of the
   default pill button shape. */
#size-dropdown-btn {
    border-radius: var(--app-radius-sm);
    font-weight: 400;
    font-size: 0.85rem;
    padding: 0.25rem 0.5rem;
    min-height: calc(1.5em + 0.5rem + 2px);
    color: var(--app-text);
    background-color: #ffffff;
    border-color: var(--app-border-strong);
}
#size-dropdown-btn:hover,
#size-dropdown-btn:focus {
    background-color: #ffffff;
    border-color: var(--app-primary);
    color: var(--app-text);
}

/* Element swatches — sizes constant, only background colour varies.
 * Inline style only needs to set `background:` */
.tl-swatch-sm {
    display: inline-block;
    width: 10px; height: 10px;
    border-radius: 2px;
    flex-shrink: 0;
}
.tl-swatch-md {
    display: inline-block;
    width: 12px; height: 12px;
    border-radius: 3px;
    flex-shrink: 0;
}

/* Progress-bar wrappers used in stats tables. Only width is dynamic. */
.tl-progress      { height: 8px; background: var(--app-panel-2); }
.tl-progress-thin { height: 7px; background: var(--app-panel-2); }

/* Parameter-diagram palette — themed via CSS vars so the inline SVG
   re-colours live with the light/dark toggle. Accent dimension colours
   (amber / cyan / green / purple) stay literal: they read on both themes. */
:root {
    --pd-bg:    #f6f7f8;   /* panel / svg background      */
    --pd-inset: #eceff1;   /* channel interior            */
    --pd-slot:  #ffffff;   /* slot holes                  */
    --pd-trunk: #fdecea;   /* trunking body / base plate  */
    --pd-title: #6b6e72;   /* section titles, legend text */
    --pd-faint: #b3b6b9;   /* sub-labels, dashed guides   */
}
html[data-bs-theme="light"] {
    --pd-bg:    #f6f7f8;
    --pd-inset: #eceff1;
    --pd-slot:  #ffffff;
    --pd-trunk: #fdecea;
    --pd-title: #6b6e72;
    --pd-faint: #b3b6b9;
}

/* Technical diagram panel (catalogue parameter diagram) */
.tl-diagram-panel {
    background: var(--pd-bg);
    border-radius: 0 0 var(--app-radius-md) var(--app-radius-md);
}
.tl-diagram-svg {
    width: 100%;
    max-width: 900px;   /* scaled down from full width; viewBox unchanged */
    height: auto;
    display: block;
    margin: 0 auto;     /* centre within the panel */
}

/* Field labels must be block-level so their bottom margin applies
 * consistently. A plain <label class="form-label"> is inline by default, and
 * vertical margins are ignored on inline boxes — so plain labels gave almost
 * no label→input gap while flex (icon) labels did, leaving the inputs in a
 * row misaligned. Forcing block makes every field's gap identical. The
 * .d-flex utility (icon labels) keeps its own display via !important. */
.form-label { display: block; }

/* Branding modal — logo preview thumbnail. Light background so a
 * white-on-transparent logo (common) is still visible. */
.tl-brand-preview {
    max-height: 60px;
    max-width: 200px;
    background: #f8fafc;
}

/* ═══════════════════════════════════════════════════════════════════════
 * CHEVRON ROTATION FOR COLLAPSE TRIGGERS
 * ═══════════════════════════════════════════════════════════════════════
 *
 * Bootstrap's collapse component sets `aria-expanded="true|false"` on
 * the trigger button. This pure-CSS rule replaces the JS handler that
 * used to listen for show.bs.collapse / hide.bs.collapse.
 */

[data-bs-toggle="collapse"] .bi-chevron-down {
    transition: transform 0.2s ease;
}
[data-bs-toggle="collapse"][aria-expanded="true"] .bi-chevron-down {
    transform: rotate(180deg);
}

/* ═══════════════════════════════════════════════════════════════════════
 * STOCK-POOL BANNER (editor-stock.js)
 * ═══════════════════════════════════════════════════════════════════════
 *
 * The banner sits inside the Cut Optimisation card, between the
 * card-header and the result body. It uses card-body padding so the
 * visual rhythm matches the surrounding card, plus a subtle accent
 * background that makes it clearly distinct from the regular result
 * area without being noisy.
 *
 * Two states:
 *   .tl-stock-banner-info     — proposal (matches found, awaiting Apply)
 *   .tl-stock-banner-success  — in-use   (Apply has been clicked)
 */

.tl-stock-banner {
    border-radius: 0;            /* edge-to-edge inside the card */
}

.tl-stock-banner-info {
    background: linear-gradient(180deg,
        rgba(222, 39, 31, 0.07) 0%,
        rgba(222, 39, 31, 0.03) 100%);
    border-left: 3px solid var(--app-primary);
}

.tl-stock-banner-success {
    background: linear-gradient(180deg,
        rgba(90, 138, 62, 0.10) 0%,
        rgba(90, 138, 62, 0.04) 100%);
    border-left: 3px solid rgb(34, 197, 94);
}

/* Details/summary disclosure inside the banner — give the summary
 * a touch of breathing room and a hover affordance. */
.tl-stock-banner details > summary {
    padding: 0.25rem 0;
    user-select: none;
}
.tl-stock-banner details > summary:hover {
    color: var(--app-text);
}

/* Tighten the inner match-table since it lives inside a card-body
 * that already supplies its own padding. */
.tl-stock-banner .table {
    margin-bottom: 0;
    background: transparent;
}

/* ═══════════════════════════════════════════════════════════════════════
 * QUICK CUT — DROP ZONE
 * ═══════════════════════════════════════════════════════════════════════
 *
 * The dropzone is the prominent empty state on quickcut.php. It accepts
 * file drag-and-drop AND serves as a visual cue that the page is
 * waiting for input. When a file is being dragged over it, the dashed
 * border tightens up to a solid primary-coloured border to confirm the
 * drop target.
 */

.tl-dropzone {
    border: 2px dashed var(--app-border-strong, #d9dbde);
    border-radius: 0.5rem;
    padding: 2.5rem 1rem;
    text-align: center;
    transition: border-color 0.15s ease, background-color 0.15s ease;
    cursor: default;
}

.tl-dropzone.is-dragover {
    border-color: var(--app-primary, #de271f);
    border-style: solid;
    background: var(--app-tint);
}

.tl-dropzone p {
    margin: 0;
}

.tl-dropzone code {
    background: rgba(0, 0, 0, 0.04);
    padding: 0.05rem 0.3rem;
    border-radius: 0.2rem;
    font-size: 0.85em;
}

/* Compact square icon buttons for table-row actions (open / download / edit /
   delete / restore). Without this, the global pill .btn rule inflates these
   single-icon controls into large circles. Matches the 32px sidebar icon
   buttons. Colours (primary / ghost / text-danger) are preserved. */
.btn[class*="act-"],
.btn.cat-edit, .btn.cat-apply, .btn.cat-cancel, .btn.cat-remove,
.btn.din-remove {
    width: 32px;
    height: 32px;
    padding: 0;
    border-radius: var(--app-radius-sm);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    flex: 0 0 auto;
}
.btn[class*="act-"] i,
.btn.cat-edit i, .btn.cat-apply i, .btn.cat-cancel i, .btn.cat-remove i,
.btn.din-remove i {
    margin: 0;
    line-height: 1;
    font-size: 0.95rem;
}


/* ── Localization editor ───────────────────────────────────────────── */
.loc-row {
    display: grid;
    grid-template-columns: minmax(150px, 240px) 1fr 1fr;
    gap: 4px 12px;
    align-items: start;
    padding: 5px 0;
    border-bottom: 1px solid var(--app-border);
}
.loc-grid.is-source .loc-row { grid-template-columns: minmax(150px, 240px) 1fr; }
.loc-row:last-child { border-bottom: 0; }
.loc-key {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--app-text-muted);
    padding-top: 6px;
    word-break: break-word;
}
.loc-ref {
    font-size: 0.82rem;
    color: var(--app-text-strong);
    padding-top: 6px;
}
.loc-val .loc-input { resize: none; overflow: hidden; }
.loc-row.is-untranslated .loc-key { color: var(--app-primary); }
.loc-row.is-untranslated .loc-input {
    border-color: var(--app-tint-border);
    background: var(--app-tint);
}
@media (max-width: 767.98px) {
    .loc-row, .loc-grid.is-source .loc-row { grid-template-columns: 1fr; }
    .loc-key { padding-top: 2px; }
}
/* ═══════════════════════════════════════════════════════════════════════
 * ADMIN DASHBOARD TILES  (admin/index.php)
 * ═══════════════════════════════════════════════════════════════════════ */

.tl-admin-tile {
    color: var(--app-text);
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.tl-admin-tile:hover {
    border-color: var(--app-primary);
    box-shadow: 0 4px 14px rgba(var(--app-primary-rgb), .12);
    transform: translateY(-1px);
}
.tl-admin-tile-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--app-radius-sm);
    background: var(--app-tint);
    border: 1px solid var(--app-tint-border);
    color: var(--app-primary);
    font-size: 1.25rem;
}

/* ── Read-only mode (viewing another user's configuration) ──────────────
   The editing controls are disabled from JS; this locks the canvas surface
   so runs/rails can't be dragged, resized or selected. */
.tl-readonly #panel-canvas,
.tl-readonly #canvas-wrapper,
.tl-readonly #qc-preview-host { pointer-events: none; }

/* Read-only: hide panel add/remove controls entirely (the per-panel remove
   button is re-rendered when switching panels, so hide it via CSS). */
.tl-readonly #btn-add-panel,
.tl-readonly #btn-add-panel-2,
.tl-readonly .js-panel-remove { display: none !important; }

/* Read-only: offcut reuse is not available. */
.tl-readonly #stock-banner-host { display: none !important; }
/* ── Start hub (index.php) tool cards ─────────────────────────────────── */
.home-tool-card {
    transition: border-color .12s ease, transform .12s ease, box-shadow .12s ease;
}
.home-tool-card:hover {
    border-color: var(--app-primary);
    transform: translateY(-2px);
}
.home-tool-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: var(--app-radius-md);
    background: var(--app-tint);
    border: 1px solid var(--app-tint-border);
    color: var(--app-primary);
    font-size: 1.5rem;
}

/* Informative cut-configuration summary shown in the Editor / Quick Cut
   (name / kerf / min-piece are set on the Start page, not edited here). */
.config-summary {
    padding: .5rem .75rem;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-md);
    background: var(--app-panel-1);
}

/* ── Panel-canvas cursor read-out ──────────────────────────────────────
   The live position chip is OVERLAID on the canvas (bottom-left), outside
   normal flow, so its appearance can never reflow the header/toolbar. */
.tl-coords-overlay {
    position: absolute;
    left: .75rem;
    bottom: .75rem;
    z-index: 5;
    pointer-events: none;       /* never intercepts canvas mouse events */
    white-space: nowrap;
}
.tl-coords-overlay:empty { display: none; }
