:root {
    --ink: #1c2024;
    --paper: #ffffff;
    --line: #e2e5e9;
    --muted: #6b7280;
    --blue: #2563eb;
    --blue-soft: #eff4ff;
    --green: #15803d;
    --green-soft: #f0fdf4;
    --radius: 10px;
}
* { box-sizing: border-box; }
body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    background: #f7f8fa;
    color: var(--ink);
    margin: 0;
    padding: 0;
}
.shell { max-width: 960px; margin: 0 auto; padding: 24px 20px 64px; }

/* Karen, 1 Sep: "the menu bar getting messy, too many listed there. make
   it show on left side bar instead" -- replaces the old horizontal
   header.top/#navMenu row (which wrapped into a multi-line mess once
   every admin-only link was added) with a fixed left sidebar on desktop
   and an off-canvas drawer on mobile. body gets a matching left margin
   below so every page's own unchanged .shell content sits clear of it. */
.sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; width: 220px;
    background: var(--paper); border-right: 1px solid var(--line);
    overflow-y: auto; padding: 18px 0; z-index: 100;
}
.sidebar-title { padding: 0 16px 14px; margin-bottom: 6px; border-bottom: 1px solid var(--line); }
.sidebar-title strong { display: block; font-size: 15px; line-height: 1.3; }
.sidebar-links { display: flex; flex-direction: column; }
.sidebar-links a { padding: 9px 16px; color: var(--ink); text-decoration: none; font-size: 14px; }
.sidebar-links a:hover { background: var(--blue-soft); color: var(--blue); }
.sidebar-footer { padding: 16px 16px 4px; font-size: 10.5px; color: var(--muted); border-top: 1px solid var(--line); margin-top: 14px; }
.sidebar-heading {
    padding: 14px 16px 4px; font-size: 11px; text-transform: uppercase;
    letter-spacing: .05em; color: var(--muted);
}
.sidebar-heading:first-of-type { padding-top: 2px; }
body { padding-left: 220px; }

/* Mobile top strip (hamburger + title) -- hidden on desktop, where the
   sidebar is always visible and doesn't need one. */
.mobile-topbar { display: none; }
.sidebar-overlay { display: none; }
.nav-toggle {
    display: none; flex: 0 0 34px; flex-direction: column; justify-content: center; gap: 4px;
    width: 34px; height: 34px; padding: 0; margin: 0;
    background: transparent; border: 1px solid var(--line); border-radius: 6px; cursor: pointer;
}
.nav-toggle span { display: block; width: 18px; height: 2px; background: var(--ink); margin: 0 auto; }

@media (max-width: 880px) {
    body { padding-left: 0; }
    .mobile-topbar {
        display: flex; align-items: center; gap: 10px; padding: 12px 16px;
        background: var(--paper); border-bottom: 1px solid var(--line);
        position: sticky; top: 0; z-index: 80;
    }
    .mobile-topbar-title { font-size: 14px; font-weight: 600; min-width: 0; }
    .nav-toggle { display: flex; }
    .sidebar {
        transform: translateX(-100%);
        transition: transform .2s ease;
        box-shadow: 2px 0 16px rgba(0,0,0,.12);
    }
    .sidebar.open { transform: translateX(0); }
    .sidebar-overlay {
        display: none; position: fixed; inset: 0; background: rgba(0,0,0,.35); z-index: 90;
    }
    .sidebar-overlay.open { display: block; }
}
h1 { font-size: 22px; margin: 0 0 20px; }
h2 { font-size: 16px; margin: 28px 0 10px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.card {
    background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius);
    padding: 20px; margin-bottom: 16px;
}
label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 4px; }
input, select, textarea {
    width: 100%; padding: 8px 10px; border: 1px solid var(--line); border-radius: 6px;
    font-size: 14px; margin-bottom: 12px; font-family: inherit;
}
.row { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0 14px; }
button:not(.nav-toggle), .btn {
    background: var(--blue); color: #fff; border: none; padding: 10px 18px;
    border-radius: 8px; font-size: 14px; cursor: pointer; text-decoration: none; display: inline-block;
}
button.secondary, .btn.secondary { background: transparent; color: var(--blue); border: 1px solid var(--blue); }
button.danger { background: #dc2626; }
table { width: 100%; border-collapse: collapse; margin-top: 8px; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); font-size: 14px; }
th { color: var(--muted); font-weight: 600; font-size: 12px; text-transform: uppercase; }
/* Karen, 26 Aug: "the item 1,2,3 show is new quote is overlap with the
   wording, hardly read. need to give me spacing" -- the item-number badge
   sits at the very top of the card via position:absolute, which floats it
   right on top of the first field's label unless the card reserves real
   space above its content for it. 34px of top padding (up from 14px) is
   that reserved space, on every screen size, not just mobile. */
.item-row { border: 1px solid var(--line); border-radius: 8px; padding: 34px 14px 14px; margin-bottom: 10px; position: relative; }
/* Karen, 26 Aug: "do allow the pricing preview item move up or down to
   rearrange the placement" -- Move up / Move down sit alongside Remove in
   one small top-right toolbar rather than each getting their own absolute
   position, so adding them didn't require re-plotting every button's own
   top/right offset. */
.item-row .item-actions { position: absolute; top: 8px; right: 10px; display: flex; align-items: center; gap: 2px; }
.item-row .item-actions button { background: none; color: var(--muted); border: none; cursor: pointer; font-size: 15px; line-height: 1; padding: 4px 6px; }
.item-row .item-actions button:disabled { opacity: .3; cursor: default; }
.item-row .item-actions button.remove { font-size: 13px; margin-left: 4px; }
/* Karen, 26 Aug: "allow it to move up as i wish. i can drag to move up
   anywhere" -- the Move up/down arrows only ever step one place at a time;
   this handle lets a card be picked up and dropped directly wherever it's
   wanted in one motion. Kept alongside the arrows rather than replacing
   them, since native drag-and-drop doesn't fire on touch devices -- the
   arrows stay as the mobile-friendly fallback. */
.item-row .drag-handle { cursor: grab; font-size: 15px; padding: 4px 4px; color: var(--muted); user-select: none; letter-spacing: -2px; }
.item-row .drag-handle:active { cursor: grabbing; }
.item-row.dragging { opacity: .4; }
.item-row .item-actions { flex-wrap: wrap; justify-content: flex-end; }
/* Karen, 26 Aug: "can the item is in list format as when i have 10 items,
   the data is alot. those naming is keep repeating" -- collapsed, a card
   shows only its one-line summary (item type, dims, area); every field
   below it is hidden entirely rather than just visually shrunk, so 10
   collapsed items genuinely take up 10 short lines, not 10 short-but-still-
   tall cards. */
.item-row .item-summary { display: none; font-size: 14px; font-weight: 600; padding-right: 110px; cursor: pointer; }
.item-row.collapsed .item-summary { display: block; }
.item-row.collapsed .item-details { display: none; }
.item-row .toggle-collapse { transition: transform .15s; }
.item-row.collapsed .toggle-collapse { transform: rotate(-90deg); }
.item-row .item-number { position: absolute; top: 12px; left: 14px; font-size: 13px; font-weight: 700; color: var(--text); text-transform: uppercase; letter-spacing: .02em; }
.total-line { display: flex; justify-content: space-between; font-size: 16px; padding: 6px 0; }
.total-line.selling { font-weight: 700; color: var(--green); font-size: 20px; border-top: 2px solid var(--line); margin-top: 8px; padding-top: 10px; }
.pill { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; background: var(--blue-soft); color: var(--blue); }
.error { background: #fef2f2; color: #b91c1c; padding: 10px 14px; border-radius: 8px; margin-bottom: 16px; }
.muted { color: var(--muted); font-size: 13px; }
/* Karen, 2 Sep: "the manage user tidy up the page" -- up to 6 action
   buttons (Edit email / Reset password / Change role / Assign senior /
   Assign tier / Remove) sitting in one row made a row with every button
   (e.g. a junior sales account) spill sideways and look cramped. Collapsed
   behind one "Actions" toggle per row instead -- same <details>/<summary>
   disclosure pattern Pricing Tiers already uses for its per-category grid.
   Nothing about what a button DOES changed, just how many show at once. */
.actions-menu summary { cursor: pointer; color: var(--blue); font-size: 13px; list-style: none; }
.actions-menu summary::-webkit-details-marker { display: none; }
.actions-menu summary::before { content: '\25B8'; display: inline-block; width: 12px; transition: transform .15s; }
.actions-menu[open] summary::before { transform: rotate(90deg); }
.actions-menu .actions-body { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin-top: 8px; min-width: 170px; }
.actions-menu .actions-body form { margin: 0; }
.actions-menu .actions-body button { width: 100%; text-align: left; }
.dim-mark { font-size: 11px; }
.dim-mark .req-star { color: #dc2626; font-weight: 700; }
.section-label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; color: var(--muted); margin: 14px 0 6px; padding-top: 10px; border-top: 1px solid var(--line); }
.section-label:first-of-type { border-top: none; padding-top: 0; }
.section-label .muted { text-transform: none; font-weight: 400; letter-spacing: normal; font-size: 12px; }
input.input-error, select.input-error { border-color: #dc2626; background: #fef2f2; }
input:disabled { background: #f3f4f6; color: var(--muted); }

/* Mobile pass -- New Quote and every other form/table page is genuinely
   usable on a phone now, not just the top nav. Kept as its own block (after
   every base rule above) so these overrides win by source order without
   needing extra selector specificity. */
@media (max-width: 720px) {
    .shell { padding: 16px 12px 48px; }
    h1 { font-size: 19px; }
    .card { padding: 14px; }
    /* Every form field stacks full-width instead of the auto-fit grid
       squeezing 2-3 narrow columns onto a phone screen. */
    .row { grid-template-columns: 1fr; gap: 0; }
    /* 16px stops iOS Safari's automatic zoom-on-focus (anything under 16px
       triggers it), which was making every tap into a field jarring. */
    input, select, textarea { font-size: 16px; padding: 10px; }
    button:not(.nav-toggle), .btn { width: 100%; padding: 12px 18px; font-size: 15px; }
    /* Buttons that sit side-by-side on desktop (Preview/Save, rate-tabs)
       still make sense inline -- only force full-width where a button is
       genuinely alone on its own line already. */
    .rate-toolbar button, .rate-tabs .btn { width: auto; }
    div[style*="margin-top:20px"] button { width: 100%; margin-bottom: 8px; }
    /* Wide tables (pricing preview, quotes list, rate grids) scroll
       horizontally instead of squashing every column unreadably thin. */
    table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    th, td { white-space: nowrap; }
    .item-row { padding: 40px 12px 14px; }
    .item-row .item-actions { top: 8px; right: 8px; max-width: calc(100% - 60px); }
    .item-row .item-actions button.remove { padding: 6px 10px; background: #fef2f2; color: #b91c1c; border-radius: 6px; }
    .item-row .item-number { top: 12px; left: 12px; }
    /* Native HTML5 drag-and-drop doesn't fire on touch -- hide the handle
       so mobile isn't shown a control that won't do anything; the Move
       up/down arrows are the touch-friendly way to reorder. */
    .item-row .drag-handle { display: none; }
    .item-row .item-summary { font-size: 15px; padding: 2px 0 2px 4px; padding-right: 0; }
}

/* Karen, 27 Aug: "item explanation is too long, make it hidden with a
   hidden function when arrow point there it appear, when not point there
   then disappear" -- collapses a long Specs cell behind a small "▸ Specs"
   toggle; the full text only appears in a floating popup on hover (or
   keyboard focus, so it's not mouse-only) and disappears the instant the
   pointer/focus leaves. Pure CSS, no JS. */
.xp-spec-toggle {
    position: relative;
    display: inline-block;
    cursor: help;
    color: var(--muted);
    border-bottom: 1px dotted var(--muted);
}
.xp-spec-toggle .xp-spec-popup {
    display: none;
    position: absolute;
    left: 0;
    top: 100%;
    margin-top: 4px;
    z-index: 30;
    background: #fff;
    border: 1px solid #e2e2e5;
    border-radius: 6px;
    padding: 8px 10px;
    box-shadow: 0 4px 14px rgba(0,0,0,.14);
    white-space: normal;
    min-width: 220px;
    max-width: 340px;
    font-size: 12px;
    line-height: 1.5;
    color: #333;
}
.xp-spec-toggle:hover .xp-spec-popup,
.xp-spec-toggle:focus .xp-spec-popup {
    display: block;
}

/* Karen, 27 Aug: "item, additional item title shorten" -- same hover-popup
   mechanism as .xp-spec-toggle above, but used next to a short field label
   (New Quote's Item details / Additional items sections) instead of
   replacing a long value. The icon itself needs no dotted underline. */
.xp-label-hint {
    border-bottom: none;
    font-style: normal;
    margin-left: 2px;
}

/* QUICK ENTRY (28 Sep) -- New Quote's "key in only what's needed" mode.
   Pure display: expert blocks are hidden, never removed, so their values
   still post exactly as before. See new_quote.php's mode-bar comment. */
.xp-mode-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; background: #f0fdf4; border-color: #bbf7d0; margin-bottom: 14px; }
.xp-quick .item-row .xp-adv { display: none !important; }
.xp-auto-hint { font-size: 12px; color: #15803d; margin: 2px 0 8px; }
.xp-adv-badge { font-size: 12px; color: #854d0e; background: #fef9c3; border: 1px solid #fde68a; border-radius: 6px; padding: 4px 8px; margin: 4px 0 8px; }

/* COLOUR CODING (28 Sep) -- one colour per cabinet family so a long quote
   can be scanned by eye. Applies to New Quote item rows, the Preview table
   and the saved quote's line table. Display only. Group list lives in
   calculator.php (XP_COLOR_GROUPS) -- keep the two in step. */
.xp-c-base     { --xp-c: #2563eb; --xp-cbg: #eff6ff; }
.xp-c-wall     { --xp-c: #16a34a; --xp-cbg: #f0fdf4; }
.xp-c-tall     { --xp-c: #9333ea; --xp-cbg: #faf5ff; }
.xp-c-wardrobe { --xp-c: #ea580c; --xp-cbg: #fff7ed; }
.xp-c-tv       { --xp-c: #db2777; --xp-cbg: #fdf2f8; }
.xp-c-table    { --xp-c: #ca8a04; --xp-cbg: #fefce8; }
.xp-c-panel    { --xp-c: #0891b2; --xp-cbg: #ecfeff; }
.xp-c-glass    { --xp-c: #64748b; --xp-cbg: #f1f5f9; }
.xp-c-stone    { --xp-c: #57534e; --xp-cbg: #f5f5f4; }
.xp-c-addon    { --xp-c: #dc2626; --xp-cbg: #fef2f2; }
.xp-c-reno     { --xp-c: #0d9488; --xp-cbg: #f0fdfa; }
.xp-c-custom   { --xp-c: #4d7c0f; --xp-cbg: #f7fee7; }
.xp-c-other    { --xp-c: #6b7280; --xp-cbg: #f9fafb; }
.item-row[class*="xp-c-"] { border-left: 6px solid var(--xp-c); background: var(--xp-cbg); }
tr[class*="xp-c-"] td { background: var(--xp-cbg); }
tr[class*="xp-c-"] td:first-child { box-shadow: inset 6px 0 0 var(--xp-c); }
.xp-legend { display: flex; flex-wrap: wrap; gap: 6px 10px; margin: 6px 0 4px; font-size: 12px; }
.xp-legend-chip { display: inline-flex; align-items: center; gap: 5px; }
.xp-legend-chip i { width: 12px; height: 12px; border-radius: 3px; background: var(--xp-c); display: inline-block; }
@media print { .xp-legend { display: none; } }

/* PHONE POLISH FOR NEW QUOTE (28 Sep). Found by reading the cascade: the
   phone rule `button:not(.nav-toggle){width:100%}` also hit every button in
   each item's toolbar (collapse / move up / move down / duplicate / remove),
   so on a phone they stacked one-per-line over the item's first fields.
   Restored to a compact, wrapping toolbar with proper (>=40px) tap targets,
   and made Preview/Save a sticky bottom bar so a long quote never needs a
   scroll back to the end to submit. Not eyeballed on a real device -- no
   browser is available in the build sandbox. */
@media (max-width: 720px) {
    .item-row .item-actions button,
    tr[class*="xp-c-"] td button { width: auto; min-width: 40px; min-height: 40px; padding: 8px 10px; font-size: 14px; }
    .item-row .item-actions { gap: 4px; }
    .item-row { padding-top: 52px; }
    .xp-mode-bar button { width: 100%; }
    .xp-legend { font-size: 11px; }
    #xpActionBar { position: sticky; bottom: 0; z-index: 70; background: var(--paper); border-top: 1px solid var(--line); margin: 16px -12px 0; padding: 10px 12px; display: flex; gap: 8px; }
    #xpActionBar button { margin-bottom: 0 !important; flex: 1; }
}

/* AMENDED-SINCE-APPROVAL (28 Sep) -- highlights only what differs from the
   last approved version. Loud on purpose: sits ABOVE the cabinet colour coding. */
/* AMENDED-SINCE-APPROVAL, REBUILT (2 Oct) -- Word-Track-Changes style per the
   design agreed on: no row tint, no "AMENDED" relabelling, no separate diff
   block. A changed item gets only a thin left bar (its mark is INLINE, in
   the spec text itself -- see xp_apply_inline_trace() and .xp-trace-* below);
   a newly added item gets the same bar in a different colour; a removed
   item's own row (built separately, not one of these classes) stays as the
   plain strike-through row it already was. Deliberately does not touch the
   row's own background, so the cabinet colour-coding underneath is never
   fought with. */
tr.xp-amend-changed td:first-child { box-shadow: inset 3px 0 0 var(--fill-warning, #ca8a04); }
tr.xp-amend-new td:first-child { box-shadow: inset 3px 0 0 var(--fill-success, #16a34a); }
.xp-trace-old { color: var(--text-muted, #9ca3af); text-decoration: line-through; }
.xp-trace-new { background: #fde047; color: #713f12; padding: 0 3px; border-radius: 3px; font-weight: 600; text-decoration: none; }
@media print { .xp-trace-old, .xp-trace-new, #xpHistoryPanel { display: none; } }

/* ACTIVITY LOG (2 Oct) -- one collapsed panel for changes-since-approval and the
   approval timeline (quote.php), and the same panel on New Quote's Preview while
   editing. Closed by default; the summary line carries the count so nobody has to
   open it just to learn whether anything changed. Native <details>, no JS. */
.xp-activity { border: 1px solid var(--line); border-radius: 8px; background: var(--paper); margin: 0 0 16px; }
.xp-activity > summary { list-style: none; cursor: pointer; padding: 10px 14px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 14px; }
.xp-activity > summary::-webkit-details-marker { display: none; }
.xp-activity > summary::before { content: '\25B8'; color: var(--muted); font-size: 12px; transition: transform .15s; }
.xp-activity[open] > summary::before { transform: rotate(90deg); }
.xp-activity > summary:focus-visible { outline: 2px solid #2563eb; outline-offset: 2px; border-radius: 8px; }
.xp-activity-title { font-weight: 600; }
.xp-activity-count { font-size: 12px; color: #92400e; background: #fef3c7; border-radius: 999px; padding: 2px 9px; }
.xp-activity-section { border-top: 1px solid var(--line); padding: 10px 14px 12px; }
.xp-activity-head { font-size: 12px; color: var(--muted); margin-bottom: 8px; }
.xp-activity-list, .xp-timeline, .xp-activity-sublist { list-style: none; margin: 0; padding: 0; }
.xp-activity-list > li { padding: 6px 0; border-bottom: 1px dashed var(--line); font-size: 13px; line-height: 1.5; }
.xp-activity-list > li:last-child { border-bottom: 0; }
.xp-activity-detail { color: var(--muted); margin-left: 4px; }
.xp-activity-detail s { color: #9ca3af; }
.xp-activity-detail strong { color: var(--ink); font-weight: 600; }
.xp-kind { display: inline-block; min-width: 62px; font-size: 11px; font-weight: 600; margin-right: 6px; }
.xp-kind-changed { color: #b45309; }
.xp-kind-added { color: #15803d; }
.xp-kind-removed { color: #b91c1c; }
.xp-up { color: #b45309; }
.xp-down { color: #15803d; }
.xp-timeline > li { position: relative; padding: 0 0 12px 18px; font-size: 13px; }
.xp-timeline > li::before { content: ''; position: absolute; left: 4px; top: 6px; width: 7px; height: 7px; border-radius: 50%; background: #cbd5e1; }
.xp-timeline > li::after { content: ''; position: absolute; left: 7px; top: 15px; bottom: 0; width: 1px; background: var(--line); }
.xp-timeline > li:last-child::after { display: none; }
.xp-activity-note { color: var(--muted); font-style: italic; margin-top: 2px; }
.xp-activity-sublist { margin-top: 4px; }
.xp-activity-sublist > li { font-size: 12px; padding: 2px 0; }
@media (max-width: 720px) { .xp-kind { min-width: 0; } }
@media print { .xp-activity { display: none; } }
/* 2 Oct: the "changed since approval" bar used to REPLACE the cabinet colour
   bar on the same cell. Now the colour bar stays, and a changed/new line gets a
   small dot in its # cell instead -- both meanings visible at once. */
tr.xp-amend-changed td:first-child, tr.xp-amend-new td:first-child { box-shadow: inset 6px 0 0 var(--xp-c, transparent); }
tr.xp-amend-changed td:first-child::after, tr.xp-amend-new td:first-child::after {
    content: ''; display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-left: 5px; vertical-align: middle; }
tr.xp-amend-changed td:first-child::after { background: #d97706; }
tr.xp-amend-new td:first-child::after { background: #16a34a; }

/* COMMERCIAL UI PASS (2 Oct) -- quote page header. */
.xp-quote-title { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.xp-quote-title > span { margin-right: 6px; }
.xp-quote-title a.btn, .xp-quote-title form, .xp-quote-title button { margin-left: 0 !important; }
@media (max-width: 720px) {
    .xp-quote-title { font-size: 20px; }
    .xp-quote-title > span { flex-basis: 100%; }
    .xp-quote-title a.btn, .xp-quote-title button { width: auto !important; min-height: 36px; padding: 6px 12px !important; }
}
.xp-quote-status { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.xp-quote-status:empty { display: none; }
.xp-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px 20px; margin: 0 0 14px; }
.xp-meta dt { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-bottom: 3px; }
.xp-meta dd { margin: 0; font-size: 14px; line-height: 1.5; }
.xp-meta a { color: inherit; }
.xp-inline-form { display: flex; gap: 6px; align-items: center; margin: 0; }
.xp-inline-form select { width: auto; margin: 0; padding: 4px 6px; font-size: 13px; }
.xp-inline-form button { width: auto !important; padding: 4px 10px !important; font-size: 12px; margin: 0; }
