/* ============================================================
   neumorphic.css — "Neumorphic UI" theme.

   Scoped entirely under body.neu-mode, so this file is inert until that class
   is on <body>.

   NOT a duplicate of embossed.css. That one is neutral grey (#f0f0f3) with
   tight radii and a fairly firm shadow. This is the cooler, softer variant from
   the reference kit: a blue-grey ground, much larger radii (pills and 22px+
   cards), and a wide diffuse shadow pair that makes elements look extruded from
   the page rather than pressed onto it.

   The whole illusion rests on one rule: EVERY surface is the same colour as the
   page. Depth comes only from the shadow pair — a white highlight up-left and a
   cool shadow down-right. The moment a panel has its own fill or a border, it
   stops looking extruded and starts looking pasted on. So there are no borders
   anywhere in this file, and no translucency: frosted glass cannot sit flush
   with the ground the way soft UI needs.
   ============================================================ */

/* Poppins carries the figures in this theme — the geometric, near-circular
   bowls in the reference kit. Only the two weights the display numbers use, so
   it stays a small request, and swap so text never blocks on it.

   Imported here rather than linked in eight page heads: the theme brings its own
   font, and nothing else in the app needs it. */

/* Paint the flat ground before JS runs, so the photo backdrop doesn't flash.
   The page sets this attribute in <head> straight from localStorage. */
html[data-boot-theme="neu"] body {
    background: #e4ebf5 !important;
    background-image: none !important;
}

body.neu-mode {
    --neu-bg:     #e4ebf5;   /* the ground everything shares */
    --neu-light:  #ffffff;   /* highlight, up-left */
    --neu-dark:   #c3cfe2;   /* shadow, down-right — cool, never grey */

    /* Inks sampled from the reference: a desaturated slate, warmer and greyer
       than the blue this theme started with. */
    --neu-ink:    #3f4a56;   /* headings and display figures */
    --neu-mid:    #5c6673;   /* body text */
    --neu-soft:   #8d97a4;   /* labels, secondary */
    --neu-faint:  #aab3c0;   /* present but inert — see .cal-day.other-month */

    /* Display figures only — see the note on the rule below. */
    --neu-figure: var(--font-ui); /* was Poppins; the house face is SF Mono everywhere now */

    /* Figures fade from the full ink down to a softer tint of the SAME slate —
       no hue shift, so it reads as light falling down the digits rather than as
       two colours. The pale end stops at #737e8c: light enough to see the fade,
       dark enough that the bottom of a digit is still solid against the card. */
    --neu-figure-grad: linear-gradient(175deg, #39434f 0%, #454f5c 42%, #737e8c 100%);

    /* Accents are deliberately NOT extruded. Soft UI hides anything sharing the
       surface colour, so the few things that must be found fast — a primary
       action, an ON state — get a solid fill and a coloured glow instead. */
    --neu-green:  #2fd07f;
    --neu-blue:   #5b8def;
    --neu-pink:   #e05f8f;

    /* The shop's red, as a fill for round controls: the theme's light slate
       (the Card arc's colour) running into the brand red, corner to corner on
       a disc. Slate rather than the brand name's black — at button size the
       black read as a hole in the bar. Used by every SEARCH button, so they
       read as the mark rather than as one more blue accent. Other accents
       (Continue, Complete Sale) stay blue. */
    --neu-mark-grad: linear-gradient(135deg, #8fa0b8 0%, #9aa3b4 35%, #dc2626 100%);

    /* The shadow pair. Two sizes: cards get the wide one, controls the tight
       one, so a button inside a card still reads as sitting on top of it. */
    /* Card surface. Strictly speaking soft UI wants panels the SAME flat colour
       as the page — depth is supposed to come only from the shadow pair. This
       breaks that a little on purpose: a very low-contrast wash reads as light
       falling across the panel rather than as a coloured fill, so the extruded
       illusion survives while the card stops looking dead flat.

       Keep these alphas low. Past roughly 0.10 the tint starts reading as the
       card's own colour and the whole surface detaches from the page.
       · white bloom top-left  — same light source as the shadows below
       · cool bloom bottom      — a deeper slate. The reference had a peach cast
         here; the shop asked for no orange anywhere in this theme (2026-09-09)
       · cool base              — very slightly deeper than --neu-bg */
    --neu-card-bg:
        radial-gradient(115% 85% at 18% 0%,   rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0) 58%),
        radial-gradient(130% 95% at 55% 118%, rgba(143, 160, 184, 0.12) 0%, rgba(143, 160, 184, 0) 62%),
        linear-gradient(158deg, #eaf0f9 0%, #e1e8f4 100%);

    /* Row version of the above — vertical only, so it can be painted per cell
       without seams. See the table section for why. Same cool-bloom idea,
       lighter still because a row is a fraction of a card's height. */
    --neu-row-bg:
        linear-gradient(180deg, rgba(255, 255, 255, 0.80) 0%, rgba(255, 255, 255, 0) 55%),
        linear-gradient(180deg, rgba(143, 160, 184, 0) 45%, rgba(143, 160, 184, 0.08) 100%),
        linear-gradient(180deg, #eaf0f9 0%, #e1e8f4 100%);

    --neu-out:    9px 9px 20px var(--neu-dark), -9px -9px 20px var(--neu-light);
    --neu-out-sm: 5px 5px 11px var(--neu-dark), -5px -5px 11px var(--neu-light);
    --neu-in:     inset 5px 5px 11px var(--neu-dark), inset -5px -5px 11px var(--neu-light);
    --neu-in-sm:  inset 3px 3px 7px var(--neu-dark), inset -3px -3px 7px var(--neu-light);

    /* A DEEP well, for a control that stays pressed — a selected calendar day,
       not a button being clicked. --neu-in-sm is 3px against --neu-out-sm's 5px,
       so a sunken control surrounded by raised ones carries LESS shadow than its
       neighbours and reads as flat rather than pushed in. This one out-shadows
       the raised state, which is what makes the well legible in a grid. */
    --neu-in-deep: inset 5px 5px 10px var(--neu-dark), inset -4px -4px 9px var(--neu-light);

    /* Pressed surface. A real well catches less light than the face around it,
       and the shadow alone does not carry that — the eye needs the tonal drop
       too. Sits between --neu-bg and --neu-dark, much nearer the former: past a
       few percent it stops reading as shade and starts reading as a fill. */
    --neu-sunk:   #dbe3ef;

    /* ── The two text depths ──
       Inverses of each other, and they have to stay inverses or the states stop
       meaning anything side by side. Light comes from the top-left, as it does
       for every shadow pair above.

       ENGRAVE: a groove has its near wall shadowed and its far wall lit, so
       dark goes up-left and the highlight down-right. The white is carrying the
       illusion; the dark is deliberately weaker, because at 12px a heavy top
       edge stops reading as depth and starts reading as a blurry glyph.

       RAISE: the same two offsets swapped. Small figures only — the big display
       numbers are gradient-filled and must use filter: drop-shadow() instead,
       since text-shadow paints in the FOREGROUND and would land on top of the
       gradient rather than behind it. See the drop-shadow block below. */
    --neu-engrave: 1px 1px 1px rgba(255, 255, 255, 0.85),
                  -1px -1px 1px rgba(63, 74, 86, 0.22);
    --neu-raise:  -1px -1px 1px rgba(255, 255, 255, 0.9),
                   1px  1px 2px rgba(63, 74, 86, 0.38);

    /* Sunk, for something that cannot take an inset shadow — an <img>, mainly.
       Inner shadows paint above the background but BELOW the element's content,
       so on a replaced element the image itself covers them and nothing shows.

       This is --neu-out-sm with its offsets negated: dark up-left, light
       down-right, the reverse of a raised control. It reads as the lip of a
       depression rather than as a true well, which is the closest an <img> can
       get — and it lets a photo and a CSS-drawn placeholder wear the SAME
       treatment. That matters more here than absolute fidelity, because the two
       alternate row to row in the same column. */
    --neu-sunk-rim: -3px -3px 6px var(--neu-dark), 3px 3px 6px var(--neu-light);

    /* Raised, at the SAME scale as --neu-sunk-rim: the offsets un-negated, so a
       disc can be flipped from socket to button by swapping one token without
       its shadow changing weight. --neu-out-sm exists for the same idea, but it
       is 5px/11px — sized for a card or a control, and heavy enough on a 34px
       disc that the shadow reads as a smudge rather than a lift. */
    --neu-raise-sm: 3px 3px 6px var(--neu-dark), -3px -3px 6px var(--neu-light);

    /* --neu-engrave as a FILTER, for text that text-shadow cannot touch.
       Gradient-filled figures are painted by clipping a background to the
       glyphs; a text-shadow is drawn in the foreground and would land on top of
       that gradient as a smear. drop-shadow() filters the element's rendered
       output — clipped gradient included — so the shade falls behind the
       glyphs. Same reason the raised headline figures use a filter.

       Offsets match --neu-engrave: dark up-left, light down-right. Kept as its
       own token rather than derived, because filter and text-shadow take
       different syntax and there is nothing to share but the intent. */
    --neu-engrave-filter: drop-shadow(-1px -1px 1px rgba(63, 74, 86, 0.30))
                          drop-shadow( 1px  1px 1px rgba(255, 255, 255, 0.95));

    /* Raised, in the FILTER form. --neu-raise is a text-shadow, which paints in
       the foreground and therefore smears any glyph whose colour comes from a
       background — the parts-card price is gradient-filled through
       background-clip:text, so a text-shadow lands on top of the gradient
       rather than behind the letters. drop-shadow() builds from the ALPHA
       channel, so it traces the glyph outline and leaves the fill alone.
       Offsets mirror --neu-raise exactly: highlight up-left, shadow
       down-right. */
    --neu-raise-filter: drop-shadow(-1px -1px 1px rgba(255, 255, 255, 0.90))
                        drop-shadow( 1px  1px 2px rgba(63, 74, 86, 0.38));

    /* Feed the app-wide tokens so components that read them land in-palette
       without needing a rule of their own here. */
    --text-primary:   var(--neu-ink);
    --text-secondary: var(--neu-mid);
    --surface:        var(--neu-bg);
    --glass-bg:       var(--neu-bg);
    --glass-border:   transparent;
    --glass-shadow:   rgba(163, 177, 198, 0.35);
    --hairline:       rgba(163, 177, 198, 0.30);

    background: var(--neu-bg) !important;
    background-image: none !important;
    color: var(--neu-mid);
}

/* ── Panels ─────────────────────────────────────────────────────────────── */
body.neu-mode .card,
body.neu-mode .card-compact,
body.neu-mode .card-wide,
body.neu-mode .hero-card,
body.neu-mode .summary-card,
body.neu-mode .cal-wrap,
body.neu-mode .checkout-card,
body.neu-mode .cart-summary {
    background: var(--neu-card-bg) !important;
    border: none !important;
    border-radius: 24px !important;
    box-shadow: var(--neu-out) !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}

/* Hover lifts rather than brightens — there is no brightness to add when the
   surface already matches the page. */
body.neu-mode .card:hover,
body.neu-mode .card-compact:hover,
body.neu-mode .card-wide:hover {
    transform: translateY(-2px);
    box-shadow: 11px 11px 24px var(--neu-dark), -11px -11px 24px var(--neu-light) !important;
}

/* Dividers inside the merged totals card. This theme sets --glass-border to
   transparent (borders break the extruded illusion) — but these rules separate
   content INSIDE one surface rather than outlining a panel, so they need a real
   colour or the three columns run together. */
body.neu-mode .totals-merged .tm-col + .tm-col {
    border-left-color: rgba(63, 74, 86, 0.13) !important;
}
@media (max-width: 700px) {
    body.neu-mode .totals-merged .tm-col + .tm-col {
        border-top-color: rgba(63, 74, 86, 0.13) !important;
    }
}

body.neu-mode .card-divider,
body.neu-mode hr {
    border: none !important;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--neu-dark), transparent) !important;
    opacity: .7;
}
/* The four By Week columns are separated by .ws-divider, which paints itself
   with var(--glass-border) — and this theme sets that to transparent a hundred
   lines up. The dividers have been in the markup all along, invisible in this
   theme only. Same treatment as above, turned through 90°: it is a vertical
   rule, so the gradient runs top to bottom and fades at both ends rather than
   butting hard into the card's padding. */
body.neu-mode .ws-divider {
    background: linear-gradient(180deg, transparent, var(--neu-dark), transparent) !important;
    opacity: .7;
}

/* ── Type ───────────────────────────────────────────────────────────────── */
body.neu-mode h1, body.neu-mode h2, body.neu-mode h3,
body.neu-mode h4, body.neu-mode .card-title, body.neu-mode .card-value {
    color: var(--neu-ink) !important;
}
body.neu-mode .card-label,
body.neu-mode .card-desc,
body.neu-mode .muted,
body.neu-mode small {
    color: var(--neu-soft) !important;
}

/* ── Display figures ────────────────────────────────────────────────────────
   Poppins goes on the BIG numbers only — the headline values you read across
   the room. Deliberately not applied to --font-num wholesale: SKU fields, the
   MS-cost codes and the money columns rely on monospace so digits stay in
   column, and Poppins has no tabular figures to give them.

   Tightened tracking because geometric faces set wide at display size, and the
   reference has its figures close together. */
body.neu-mode .card-value,
body.neu-mode .ws-value,
/* drawer card: the openings count in the ring's hole */
body.neu-mode .dc-ring-fig,
body.neu-mode .summary-value,
body.neu-mode .hero-cur,
body.neu-mode .hero-gauge-nums,
body.neu-mode .totals-row,
/* These carry an inline colour and font-size in index.php, which is why they
   need !important below and why they were missed by the class selectors. */
body.neu-mode #bankBalance,
body.neu-mode #paymentsTotal,
body.neu-mode #expGrandTotal,
body.neu-mode #othersBalance,
/* Cart grand totals — repairs checkout and the main checkout */
body.neu-mode .summary-total span,
body.neu-mode .receipt-total-row.grand-total span,
/* Product cards on checkout: the price and battery figures */
body.neu-mode .gsm-hero b {
    font-family: var(--neu-figure) !important;
    font-weight: 700 !important;
    letter-spacing: -0.02em !important;
    color: var(--neu-ink) !important;
    font-variant-numeric: normal;
}

/* Gradient fill on the figures.
   Guarded by @supports because the technique paints the text with a background
   and then makes the glyphs themselves transparent — where that isn't supported
   the numbers would vanish entirely rather than degrade. Inside the guard the
   solid colour above is still the fallback, so nothing is ever unpainted. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    body.neu-mode .card-value,
    body.neu-mode .ws-value,
    /* drawer card: the openings count in the ring's hole */
    body.neu-mode .dc-ring-fig,
    body.neu-mode .summary-value,
    body.neu-mode .hero-cur,
    body.neu-mode .hero-gauge-nums,
    body.neu-mode #bankBalance,
    body.neu-mode #paymentsTotal,
    body.neu-mode #expGrandTotal,
    body.neu-mode #othersBalance,
    body.neu-mode .summary-total span,
    body.neu-mode .receipt-total-row.grand-total span,
    body.neu-mode .gsm-hero b {
        background: var(--neu-figure-grad) !important;
        -webkit-background-clip: text !important;
        background-clip: text !important;
        -webkit-text-fill-color: transparent !important;
        /* Each figure gets its own ramp rather than inheriting a slice of a
           taller one, so a small value fades the same way a large one does. */
        background-size: 100% 100% !important;
        background-repeat: no-repeat !important;
    }
}

/* Raised digits, as in the reference card — the figure looks extruded from the
   surface like everything else in this theme, rather than printed on it.

   filter: drop-shadow(), NOT text-shadow. A text shadow is painted with the
   FOREGROUND, so on gradient-filled text it lands on top of the gradient and
   reads as a blur across the digits. drop-shadow() filters the element's
   rendered output — the clipped gradient included — so the shadow falls behind
   the glyphs where it belongs.

   Big figures only. At 12–14px the same offsets just read as a printing fault.

   HOUSE STANDARD for large amounts. When a new page gets a headline figure, add
   its selector to all THREE lists — the font rule, the @supports gradient block,
   and this filter — or it will pick up part of the treatment and look broken
   next to the others. */
body.neu-mode .card-value,
body.neu-mode #bankBalance,
body.neu-mode #paymentsTotal,
body.neu-mode #expGrandTotal,
body.neu-mode #othersBalance,
body.neu-mode .hero-gfval,
/* admin_parts: Total Inventory Cost / Potential Revenue / Potential Profit (32px) */
body.neu-mode .summary-value,
/* Sales / Cost / Profit / Taxes By Week (1.2rem — the smallest figure that still
   carries the raise; below this the offsets read as a printing fault). */
body.neu-mode .ws-value,
/* drawer card: the openings count in the ring's hole */
body.neu-mode .dc-ring-fig,
/* repairs + main checkout: the cart grand total */
body.neu-mode .summary-total span,
body.neu-mode .receipt-total-row.grand-total span,
/* Product cards on checkout: the price and battery figures */
body.neu-mode .gsm-hero b,
/* Coloured, but raised like the rest — the filter shadows the glyph shape and
   doesn't care what colour fills it. */
body.neu-mode .hero-vs-delta {
    /* Light from top-left, matching the shadow pair on every panel. */
    filter:
        drop-shadow(-1px -1px 1px rgba(255, 255, 255, 0.95))
        drop-shadow(2px 2px 3px rgba(146, 162, 188, 0.55));
}

/* Drawer card: the ring's callout names and the caption under its figure.
   SVG text does not reliably take text-shadow, so the name uses the filter
   form; the caption is HTML and takes the shadow directly. Raised figure over
   engraved label is the house pairing — the figure above is in the raise list
   a few lines up. */
body.neu-mode .dc-ring-lname {
    filter: var(--neu-engrave-filter);
}
body.neu-mode .dc-ring-cap-l {
    text-shadow: var(--neu-engrave);
}

/* ── Engraved figures ───────────────────────────────────────────────────────
   Every SMALL number in the theme, cut into the surface it sits on. Between
   this and the drop-shadow block above, each figure now reads as either carved
   in or extruded out, and nothing is merely printed flat.

   The list is dashboard.css's "Figures" selector list MINUS the headline
   figures, which are handled above. Do not merge the two: a big figure is
   gradient-filled, and text-shadow paints in the foreground — it would sit ON
   TOP of the gradient as a smear across the digits. That is the whole reason
   the raised block uses filter: drop-shadow() instead.

   .topbar-badge is left out on purpose. It is white text on a red pill, and a
   white highlight below-right of white glyphs is not a groove, just a blur.
   Engraving needs a surface lighter than its ink.

   .cal-day is not repeated here — it carries --neu-engrave in the calendar
   section, where it sits beside the raised state it is defined against.

   Adding a new small figure? Put it here. Adding a new HEADLINE figure? It goes
   in all three lists above instead — see the note on the drop-shadow block. */
body.neu-mode .amount-val,
body.neu-mode .foot-total,
body.neu-mode .rev-stat-val,
body.neu-mode .chip-num,
body.neu-mode .val-amount,
body.neu-mode .val-cost-on,
body.neu-mode .val-cost-off,
body.neu-mode .val-profit,
body.neu-mode .val-profit-neg,
body.neu-mode .profit-pct,
body.neu-mode .seller-amount,
body.neu-mode .vbar-pill .vbar-amount,
/* Dashboard figures that index.php styles inline and so never reached the
   Figures list. All 12–18px on a light card, which is where engraving works. */
body.neu-mode #squareFees,
body.neu-mode #squareSavings,
body.neu-mode #squareNet,
body.neu-mode #dedTodayIn,
body.neu-mode #dedTodayOut,
body.neu-mode #bankTodayIn,
body.neu-mode #bankTodayOut,
body.neu-mode #bankLogWeekIn,
body.neu-mode #bankLogWeekOut {
    text-shadow: var(--neu-engrave);
}

/* Card titles pick up the same face a weight down, matching how the reference
   pairs its label with the figure beneath it. */
body.neu-mode .card-title,
body.neu-mode .table-title,
body.neu-mode h1, body.neu-mode h2, body.neu-mode h3 {
    font-family: var(--neu-figure) !important;
    font-weight: 600 !important;
    letter-spacing: -0.01em;
}

/* Headings and eyebrows, cut in like everything below them. Kept out of the
   rule above because that one is about the FACE — a heading elsewhere may want
   the Poppins without the groove, and .table-subtitle wants the groove without
   the Poppins. */
body.neu-mode .card-title,
body.neu-mode .table-title,
body.neu-mode .table-subtitle,
body.neu-mode .card-label,
body.neu-mode h1, body.neu-mode h2, body.neu-mode h3 {
    text-shadow: var(--neu-engrave);
}

/* ── Chrome ─────────────────────────────────────────────────────────────── */
body.neu-mode .topbar,
body.neu-mode .sidenav {
    background: var(--neu-bg) !important;
    background-image: none !important;
    border: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    box-shadow: var(--neu-out) !important;
}
body.neu-mode .topbar { border-radius: 0 0 24px 24px !important; }

/* The rail, lifted like a card and given an edge. The chrome rule above gave it
   the ground colour and the even all-round shadow, and against a page of the
   same value the boundary dissolved — the rail read as part of the page. Two
   things fix that, both in the theme's own language: the card surface (one
   step lighter, white bloom top-left) so it sits UP like every card does, and
   an edge — a 1px lit lip along its right side, and a shadow cast onto the
   page to the right rather than evenly all round. No colour change: a darker
   or coloured rail would be the one surface in the theme that is not the same
   material as the ground. */
body.neu-mode .sidenav {
    background: var(--neu-card-bg) !important;
    box-shadow:
        inset -1px 0 0 rgba(255, 255, 255, 0.95),
        14px 0 28px -8px var(--neu-dark),
        4px 0 10px -6px rgba(63, 74, 86, 0.18) !important;
}

body.neu-mode .sidenav a,
body.neu-mode .sidenav .nav-item {
    color: var(--neu-soft) !important;
    border-radius: 14px !important;
}
body.neu-mode .sidenav a:hover,
body.neu-mode .sidenav .nav-item:hover {
    color: var(--neu-ink) !important;
    box-shadow: var(--neu-out-sm) !important;
}
/* The current page is pressed IN — the one place an inset reads as "you are
   here" rather than as an input. */
body.neu-mode .sidenav a.active,
body.neu-mode .sidenav .nav-item.active {
    color: var(--neu-blue) !important;
    box-shadow: var(--neu-in-sm) !important;
}

/* ── Side nav items, finished ───────────────────────────────────────────────
   The block above themes the panel and the states; this finishes the items.
   index.css paints every item with a white gradient, tints the current page
   orange with a 3px bar, and paints the label with a blue-to-red gradient
   clipped to the text — none of which the colour rules above could reach (a
   clipped gradient ignores `color`), so in soft UI the nav read as a stack of
   white cards with a stray orange highlight.

   Items sit flat on the panel, pulled in from the edges so the raised (hover)
   and pressed (current page) shadows have room to show. The fill on those two
   states is the GROUND colour, not a tint: a raised or sunk object is the same
   colour as the surface it belongs to. Collapsed the panel is 64px, so the
   inset leaves a 52px pill with the 28px icon centred in it. */
body.neu-mode .sidenav .nav-item {
    background: transparent !important;
    margin: 2px 6px;
    padding-left: 12px;
}
body.neu-mode .sidenav .nav-item::before { display: none; }
body.neu-mode .sidenav .nav-item:hover,
body.neu-mode .sidenav .nav-item.active {
    background: var(--neu-bg) !important;
}
/* The label: plain ink that follows the item's colour (soft at rest, ink on
   hover, blue on the current page), engraved like every other label in the
   theme. The gradient AND the transparent fill it relied on both have to go,
   or the text vanishes. opacity/transform are left alone — they are the
   collapse-and-expand animation. */
body.neu-mode .sidenav .nav-label {
    background: none;
    -webkit-background-clip: initial;
    background-clip: initial;
    -webkit-text-fill-color: currentColor;
    color: inherit;
    filter: none;
    text-shadow: var(--neu-engrave);
}
/* Icons: there is nothing left to correct here. This was a raised disc and a
   grayscale filter, and both were written for the webicon/*.png the rail used
   to carry — the disc gave a flat square picture an edge to sit on, and the
   filter pulled out colour the picture supplied whether the theme wanted it or
   not. The rail draws stroked SVGs now (the nav_* set in icons.php) and they
   take currentColor, so they are already this theme's grey at rest and its
   blue on the current page, with no edge to invent.

   Kept as an explicit reset instead of deleted: a disc is a box-shadow on a
   24px box that is now transparent, so leaving it would ring twenty-two
   glyphs with a floating square. */
body.neu-mode .sidenav .nav-icon {
    box-shadow: none;
    filter: none;
}
body.neu-mode .sidenav .nav-section-label { color: var(--neu-soft); text-shadow: var(--neu-engrave); }
body.neu-mode .sidenav .nav-divider { background: var(--neu-dark); margin: 8px 14px; }

/* ── Topbar, finished ───────────────────────────────────────────────────────
   The chrome rule above paints the bar itself; index.css still lays two white
   diagonal slabs over it (::before/::after), skews white divider lines and a
   white hover fill between the quick links, paints the brand name in a
   blue-to-orange gradient, wraps the search in a white glass pill and hands the
   dropdowns frosted glass. On the soft ground all of that read as another
   theme's bar sitting on top of this one. The bells and the user chip need
   nothing here — the button catch-all below already raises them. */
body.neu-mode .topbar::before,
body.neu-mode .topbar::after,
body.neu-mode .topbar-diag,
body.neu-mode .topbar-action::before { display: none; }

/* Quick links: pills, flat at rest, lifting on hover like the side nav. */
body.neu-mode .topbar-action {
    height: 40px; margin: 0 3px; padding: 0 14px; border-radius: 999px;
    color: var(--neu-mid);
    transition: box-shadow .2s ease, color .2s ease;
}
body.neu-mode .topbar-action:hover { background: var(--neu-bg); box-shadow: var(--neu-out-sm); color: var(--neu-ink); }
body.neu-mode .topbar-action-label { color: inherit; text-shadow: var(--neu-engrave); }
body.neu-mode .topbar-action:hover .topbar-action-label { color: var(--neu-blue); }

/* Brand: the NAME keeps a gradient, but in this theme it is the logo's own
   colours — black running into red — rather than the blue-to-orange the other
   themes wear. The token is set on <body> so it beats the :root default, and
   only when no explicit choice is saved on the device (html[data-brand]), so
   ?brand=red / ?brand=black still win here too. */
html:not([data-brand]) body.neu-mode { --brand-grad: linear-gradient(90deg, #0b1220 0%, #1f2937 40%, #dc2626 100%); }
/* And it RISES off the bar, the way the headline figures rise off their cards:
   the same light-and-dark drop-shadow filter they use. A filter, not a
   text-shadow — on gradient-filled text a text-shadow paints over the fill as
   a smear, which is why the base sheet's flat 1px shadow is switched off. */
body.neu-mode .topbar-brand-name { filter: var(--neu-raise-filter); text-shadow: none; }
body.neu-mode .topbar-brand-sub  { color: var(--neu-soft); text-shadow: var(--neu-engrave); }
body.neu-mode .topbar-brand-logo { box-shadow: var(--neu-out-sm); }

/* Search: the WRAP is the well and the field inside it is bare. Left alone, the
   input rule below sinks the field inside a pill that is itself a white dish —
   a well inside a dish. Only while OPEN: collapsed it is just the button, and a
   well with nothing in it would read as a hole in the bar. The button keeps its
   blue: it is an accent, and the theme leaves accents solid on purpose (see
   the Accent actions block). */
body.neu-mode .topbar-search-wrap.is-open {
    background: #fff !important; border: none !important;
    box-shadow: var(--neu-in-sm) !important;
    backdrop-filter: none; -webkit-backdrop-filter: none;
}
body.neu-mode .topbar-search-wrap.is-open:focus-within { box-shadow: var(--neu-in-sm), 0 0 0 2px rgba(91, 141, 239, 0.35) !important; }
body.neu-mode .topbar-search-wrap .topbar-search-input {
    background: transparent !important; box-shadow: none !important;
    border-radius: 0 !important; color: var(--neu-ink) !important;
}
body.neu-mode .topbar-search-icon { color: var(--neu-soft); opacity: 1; }
body.neu-mode .topbar-search-btn {
    background: var(--neu-mark-grad) !important;
    border: none !important; border-radius: 50% !important;
    box-shadow: 0 4px 14px rgba(220, 38, 38, 0.28) !important;
}
body.neu-mode .topbar-search-btn:hover { filter: brightness(1.08); box-shadow: 0 6px 18px rgba(220, 38, 38, 0.38) !important; }

/* Right side. A bell stays pressed while its menu is open — :has() reads the
   .open the script puts on the dropdown, so no markup changes. */
body.neu-mode .topbar-sep { background: var(--neu-dark); }
body.neu-mode .topbar-notif-wrap:has(.open) > .topbar-icon-btn { box-shadow: var(--neu-in-sm); }
body.neu-mode .topbar-user-wrap:has(.open) > .topbar-user-btn  { box-shadow: var(--neu-in-sm); }
body.neu-mode .topbar-user-name { color: var(--neu-ink); text-shadow: var(--neu-engrave); }
body.neu-mode .topbar-user-role,
body.neu-mode .topbar-chevron   { color: var(--neu-soft); }
/* The avatar sits in a socket, like the seller faces on the dashboard. */
body.neu-mode .topbar-avatar {
    background: var(--neu-bg); border: none; color: var(--neu-mid);
    box-shadow: var(--neu-sunk-rim); text-shadow: var(--neu-engrave);
}

/* The three menus: raised cards on the ground, not frosted glass. */
body.neu-mode .search-dropdown,
body.neu-mode .notif-dropdown,
body.neu-mode .user-dropdown {
    background: var(--neu-card-bg) !important; border: none !important;
    box-shadow: var(--neu-out) !important;
    backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
}

/* ── Controls ───────────────────────────────────────────────────────────── */
/* NO !important on the paint here, matching embossed.css. Accent buttons like
   .search-circle-btn declare their gradient with !important precisely so this
   kind of catch-all can't flatten them — and !important beats any specificity.
   Adding it here would win that fight and repaint the one control on each step
   the operator is meant to find. */
body.neu-mode button:not(.emb-seg-btn):not(.accent-btn):not(.pcf-btn):not(.pos-unthemed),
body.neu-mode .btn,
body.neu-mode .icon-btn,
body.neu-mode .cal-nav-btn {
    background: var(--neu-bg);
    background-image: none;
    border: none;
    border-radius: 999px;
    color: var(--neu-mid);
    box-shadow: var(--neu-out-sm);
    transition: box-shadow .16s ease, color .16s ease, transform .12s ease;
}
body.neu-mode button:not(.emb-seg-btn):not(.accent-btn):not(.pcf-btn):not(.pos-unthemed):hover,
body.neu-mode .btn:hover,
body.neu-mode .icon-btn:hover {
    color: var(--neu-ink);
    box-shadow: 7px 7px 14px var(--neu-dark), -7px -7px 14px var(--neu-light);
}
/* Pressing pushes the control INTO the surface. This is the whole language of
   the style — a soft-UI button that only changes colour reads as broken. */
body.neu-mode button:not(.emb-seg-btn):not(.accent-btn):not(.pcf-btn):not(.pos-unthemed):active,
body.neu-mode .btn:active,
body.neu-mode .icon-btn:active {
    box-shadow: var(--neu-in-sm);
    transform: none;
}

/* ── Buttons that STAY chosen ───────────────────────────────────────────────
   The catch-all above is `body.neu-mode button:not(...):not(...)` — (0,3,2) —
   which outranks every `.some-btn.active` rule in the app at (0,2,0). So this
   theme was repainting selected buttons identically to unselected ones, and on
   the checkout page you could not see which payment type or status you had
   picked. auroraui.css and embossed.css both carry an override for exactly this
   list; neumorphic.css never did. That is the whole bug.

   Pressed, not tinted: in soft UI a chosen control sits IN the surface. Same
   language as the selected calendar day — deep inset, tonal drop, and it holds
   through :hover, which the catch-all's hover rule would otherwise lift back
   out at the moment you moved the pointer to look at it.

   Colour still carries which one: the accent stays on the label, so Paid reads
   green and Deposit amber exactly as the base sheets intend. Only the surface
   is themed here.

   ADDING A NEW SELECTABLE BUTTON? It goes in this list, in auroraui.css, and in
   embossed.css. Miss one and that theme silently loses its selected state. */
body.neu-mode .payment-icon-btn.active,
body.neu-mode .split-toggle-btn.active,
body.neu-mode .status-pill-btn.active,
body.neu-mode .device-loc-btn.active,
body.neu-mode .dep-method-btn.active,
body.neu-mode .csc-radio.on,
body.neu-mode .payment-icon-btn.active:hover,
body.neu-mode .split-toggle-btn.active:hover,
body.neu-mode .status-pill-btn.active:hover,
body.neu-mode .device-loc-btn.active:hover,
body.neu-mode .dep-method-btn.active:hover,
body.neu-mode .csc-radio.on:hover {
    background: var(--neu-sunk) !important;
    border-color: transparent !important;
    box-shadow: var(--neu-in-deep) !important;
}

/* ── …and their CONTENTS ────────────────────────────────────────────────────
   The rule above swaps the surface and stops. The base sheet paints all of
   these `color: #fff !important` because there it is white-on-gradient — so
   with the gradient replaced by --neu-sunk (#dbe3ef) the label went white on
   near-white and the chosen option read as blank. "Pay on Pickup" and "In
   Store" vanished entirely once selected.

   The surface already says which one is chosen, by being pressed in. The text
   only has to be readable, so it takes the theme's ink and the same cut-in as
   every other chosen control. */
body.neu-mode .payment-icon-btn.active,
body.neu-mode .split-toggle-btn.active,
body.neu-mode .status-pill-btn.active,
body.neu-mode .device-loc-btn.active,
body.neu-mode .dep-method-btn.active,
body.neu-mode .payment-icon-btn.active:hover,
body.neu-mode .split-toggle-btn.active:hover,
body.neu-mode .status-pill-btn.active:hover,
body.neu-mode .device-loc-btn.active:hover,
body.neu-mode .dep-method-btn.active:hover {
    color: var(--neu-ink) !important;
    text-shadow: var(--neu-engrave);
}
/* Same story one level down: the base crushes this artwork to solid white with
   `brightness(0) invert(1)` so it survives the blue end of the gradient. There
   is no gradient here and white artwork on a light well is nothing at all —
   let the icons keep their own colours. */
body.neu-mode .device-loc-btn.active .device-loc-icon img,
body.neu-mode .payment-icon-btn.active img {
    filter: none !important;
}
/* And the status dot, white-on-white for the same reason. */
body.neu-mode .status-pill-btn.active .status-pill-dot {
    background: var(--neu-ink) !important;
    box-shadow: var(--neu-in-sm) !important;
}

/* ── The sourcing radio's indicator ─────────────────────────────────────────
   repairs.css lights the chosen dot with a white bloom — two stacked white
   box-shadows out to 18px. That is built for the base theme, where the pill
   underneath is a saturated blue→orange gradient and white light reads as
   light. The rule above replaces that pill with --neu-sunk (#dbe3ef), and
   white glow on a near-white surface is not a glow, it is a smudge: the bloom
   has nothing to be brighter THAN, so it just fogs the pill.

   Soft UI signals "on" with depth, not brightness. So the ring becomes a well
   cut into the pill and the core a solid disc of house blue sitting in it —
   the same move as the selected calendar day, and the only coloured thing in
   the chip, which is what makes it findable.

   The unselected dot gets the same well WITHOUT the blue, so the two states
   differ by the one thing that matters. Its base border is a flat #cbd5e1
   ring, which floats on this surface like a sticker.

   SCOPED TO NEU ON PURPOSE — aurora and embossed both keep a coloured pill
   under the dot, so the white bloom still reads correctly there. */
body.neu-mode .csc-dot {
    border-color: transparent !important;
    background: var(--neu-sunk) !important;
    box-shadow: var(--neu-in-sm) !important;
}
body.neu-mode .csc-radio.on .csc-dot {
    border-color: transparent !important;
    background: var(--neu-sunk) !important;
    box-shadow: inset 2px 2px 4px var(--neu-dark),
                inset -2px -2px 4px var(--neu-light) !important;
}
body.neu-mode .csc-radio.on .csc-dot::after {
    background: var(--brand-blue, #1a5fa8) !important;
    box-shadow: none !important;
}
/* The label sits on a light well now, so it takes the theme's ink and the same
   cut-in as every other chosen control. Left as the base sheet's #fff it would
   be white text on #dbe3ef. */
body.neu-mode .csc-radio.on {
    color: var(--neu-ink) !important;
    text-shadow: var(--neu-engrave);
}
/* Focus ring has to beat the two rules above, which are !important. */
body.neu-mode .csc-radio input:focus-visible + .csc-dot {
    box-shadow: 0 0 0 3px rgba(26, 95, 168, 0.35) !important;
}

/* ── Accent actions ─────────────────────────────────────────────────────────
   Same treatment embossed.css gives these: keep the blue→orange ramp and a
   coloured glow instead of the surface. Soft UI hides anything sharing the page
   colour, so Continue / Search / Complete Sale — the one thing to press on each
   step — must not be extruded like everything else. */
body.neu-mode .accent-btn,
body.neu-mode .btn-primary,
body.neu-mode .checkout-btn,
body.neu-mode .search-circle-btn,
body.neu-mode .co-next:not(:disabled),
body.neu-mode .complete-order-btn:not(:disabled) {
    background: linear-gradient(135deg, var(--accent2, #2980d4), var(--accent, #F97316)) !important;
    color: #fff !important;
    border: none !important;
    box-shadow: 0 4px 14px rgba(26, 95, 168, 0.32) !important;
}
body.neu-mode .search-circle-btn { border-radius: 50% !important; }

body.neu-mode .accent-btn:hover,
body.neu-mode .checkout-btn:hover,
body.neu-mode .search-circle-btn:hover,
body.neu-mode .co-next:not(:disabled):hover,
body.neu-mode .complete-order-btn:not(:disabled):hover {
    filter: brightness(1.06);
    box-shadow: 0 6px 18px rgba(26, 95, 168, 0.42) !important;
}

/* A locked step reads as a well, not just a dimmed button. */
body.neu-mode .co-next:disabled,
body.neu-mode .complete-order-btn:disabled {
    background: var(--neu-bg) !important;
    background-image: none !important;
    border: none !important;
    box-shadow: var(--neu-in-sm) !important;
    color: var(--neu-soft) !important;
    filter: none !important;
}

/* ── Inputs sit in wells ────────────────────────────────────────────────── */
body.neu-mode input[type="text"],
body.neu-mode input[type="search"],
body.neu-mode input[type="number"],
body.neu-mode input[type="date"],
body.neu-mode input[type="tel"],
body.neu-mode select,
body.neu-mode textarea,
body.neu-mode .search-input {
    background: var(--neu-bg) !important;
    background-image: none !important;
    border: none !important;
    border-radius: 999px !important;
    color: var(--neu-ink) !important;
    box-shadow: var(--neu-in-sm) !important;
    outline: none !important;
}
body.neu-mode textarea { border-radius: 18px !important; }
body.neu-mode input::placeholder,
body.neu-mode textarea::placeholder { color: var(--neu-soft) !important; }
/* The SAME type list as the rule above, not a bare `input`.
 *
 * `input:focus` reached radios and checkboxes too, and handed them a well
 * meant for a text field: --neu-in is a deep inset shadow, which on a 16px
 * round control paints a grey square inside it, and the 2px ring squares off
 * the outside. A selected radio came out as a blue box with a grey blob in it.
 *
 * The block above got this right by listing the types it wanted; this one
 * inherited the intent but not the filter. */
body.neu-mode input[type="text"]:focus,
body.neu-mode input[type="search"]:focus,
body.neu-mode input[type="number"]:focus,
body.neu-mode input[type="date"]:focus,
body.neu-mode input[type="tel"]:focus,
body.neu-mode input[type="password"]:focus,
body.neu-mode select:focus,
body.neu-mode textarea:focus {
    box-shadow: var(--neu-in), 0 0 0 2px rgba(91, 141, 239, .22) !important;
}

/* Radios and checkboxes keep their native shape. They still need a visible
   focus state for keyboard use — :focus-visible only, so clicking one does not
   leave a ring behind the way :focus did. */
body.neu-mode input[type="radio"],
body.neu-mode input[type="checkbox"] {
    accent-color: var(--brand-blue, #1a5fa8);
}
body.neu-mode input[type="radio"]:focus-visible,
body.neu-mode input[type="checkbox"]:focus-visible {
    outline: 2px solid rgba(91, 141, 239, .55);
    outline-offset: 2px;
}

/* Card icons: slightly stronger than the default, since a thin stroke at 42%
   nearly vanishes against this theme's low-contrast card wash. */
/* Raised, exactly like the display figures — identical offsets and alphas, not
   an approximation, so the icon and the number beside it are lit by the same
   light at the same height.

   opacity is 1 ON PURPOSE. `opacity` fades the element AFTER the filter runs,
   so it dims the drop-shadow along with the shape — which is what made the
   first attempt look flat and muddy rather than raised. The icon is muted with
   COLOUR instead, leaving the shadow at full strength.

   (The duotone parts still recede: their fill-opacity is per-shape and applies
   before the filter, so a .32 bar correctly casts a fainter shadow than a solid
   one.) */
body.neu-mode .tc-icon-svg {
    color: var(--neu-soft) !important;
    opacity: 1;
    filter:
        drop-shadow(-1px -1px 1px rgba(255, 255, 255, 0.95))
        drop-shadow(2px 2px 3px rgba(146, 162, 188, 0.55));
}
body.neu-mode .totals-card:hover .tc-icon-svg,
body.neu-mode .tm-col:hover .tc-icon-svg {
    color: var(--neu-mid) !important;
    opacity: 1;
}

/* The caption under each of the four totals figures — Total Sales, Total Cost,
   Total Profit, Card Payments. A sibling of .card-value, never a parent, so the
   raised figure above it is out of reach. */
body.neu-mode .tc-label {
    text-shadow: var(--neu-engrave);
}

/* ── The rest of the Card Payments card ──
   Engraved at the CONTAINER, which is the exception to how the rest of this
   file works. Everything inside — the Square Fees / Loan Payment / Net Sales
   captions, the transaction count, the status line, the trend block's label,
   average and note — is an inline-styled div with no class to hang a rule on.
   Listing them by id would be a dozen selectors that silently miss the next
   line someone adds.

   Which makes the reset below load-bearing rather than defensive: text-shadow
   inherits, and .card-value is gradient-filled, so without this the $47.86
   would take a shadow painted in the FOREGROUND — a smear across the digits
   instead of the drop-shadow raise it gets near the top of this file.

   Anything gradient-filled added inside this card needs the same reset. */
body.neu-mode #squareCardContent {
    text-shadow: var(--neu-engrave);
}
body.neu-mode #squareCardContent .card-value {
    text-shadow: none;
}

/* ── Transaction log rows ──
   The bank and deductibles logs, both tabs of each, both renderers of each —
   seven copies of the same row, every one of them built from inline styles with
   nothing to select on. .txn-row and .txn-ico were added to all seven rather
   than reaching for structural selectors, which would have been seven fragile
   rules describing the same thing.

   Engraving the row reaches the type, the time-and-initials line, the amount
   and the running balance in one pass. Nothing gradient-filled lives in these
   rows, so unlike the Card Payments card there is no reset to make. */
body.neu-mode .txn-row {
    text-shadow: var(--neu-engrave);
}

/* The arrow disc, sunk. Rim only — the inline background is a red or green tint
   at 8% and it is carrying meaning next to a coloured arrow, so --neu-sunk is
   NOT applied over it. That makes this a shallower depression than the seller
   avatars get, which is the trade for keeping the in/out colour. */
body.neu-mode .txn-ico {
    box-shadow: var(--neu-sunk-rim) !important;
}

/* ── Deductibles category rows ──
   Same container approach as the card above, and for the same reason: the name,
   the amount and the "7:14 PM · Luis" line are all inline-styled spans with no
   class between them.

   The week strip is EXCLUDED at Luis's call. Its letters are 9px and its
   figures 9.5px, and below roughly 12px an engrave stops reading as depth and
   starts reading as a blurry glyph — the same limit that keeps the dark side of
   --neu-engrave weak in the first place. The reset has to be here rather than
   simply omitted, because text-shadow inherits and .ded-week sits inside the
   row. */
body.neu-mode .ded-cat-row {
    text-shadow: var(--neu-engrave);
}
body.neu-mode .ded-cat-row .ded-week {
    text-shadow: none;
}

/* ── By Week cards ──────────────────────────────────────────────────────────
   Everything except the figure.

   .ws-vs and .ws-pct are listed individually rather than engraving the
   .ws-valrow that now holds all three. That row is the whole point: it puts the
   comparison next to the figure — and .ws-value is gradient-filled and raised,
   so an inherited text-shadow would smear across it in the foreground instead
   of falling behind. The container was safe to engrave when the vs-line lived
   in its own row; it stopped being safe the moment they were joined. */
body.neu-mode .ws-label,
body.neu-mode .ws-vs,
body.neu-mode .ws-pct {
    text-shadow: var(--neu-engrave);
}

/* The ring TRACK is a groove and the arc sits in it — the same relationship the
   gauge has, one size down. drop-shadow() rather than box-shadow for the same
   reason as there: these are stroked SVG circles, and box-shadow would trace
   the element's box instead of following the ring.

   The arc gets no depth of its own. It is what fills the channel, and giving
   both a treatment would have two light sources in a 72px circle. */
body.neu-mode .ws-ring-track {
    stroke: var(--neu-sunk) !important;
    filter: drop-shadow(-1px -1px 1px var(--neu-dark))
            drop-shadow( 1px  1px 1px var(--neu-light));
}
/* Figure engraved, caption engraved — same as every other small figure here.
   Not gradient-filled, so plain text-shadow is correct. */
body.neu-mode .ws-ring-val,
body.neu-mode .ws-ring-lab {
    text-shadow: var(--neu-engrave);
}

/* ── Category bars ──────────────────────────────────────────────────────────
   Tracks are wells: the bar is a measure carved into the surface, and an inset
   reads as depth to be filled. The default track has a translucent fill, a
   border and a blur — all three break the illusion here, so they go. */
body.neu-mode .vbar-track {
    background: var(--neu-bg) !important;
    border: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    box-shadow: var(--neu-in-sm) !important;
    overflow: hidden;
}

/* The biggest earner in each group lifts OUT of its well — the one bar you want
   found first shouldn't share the recessed treatment with the rest. Marked by
   markTallestBars() in index.php, which reads the rendered heights. */
body.neu-mode .vbar-pill.is-max .vbar-track {
    box-shadow: var(--neu-out-sm) !important;
    transform: translateY(-2px);
}
body.neu-mode .vbar-pill.is-max .vbar-amount {
    color: var(--neu-ink) !important;
    font-weight: 800;
}
body.neu-mode .vbar-pill.is-max .vbar-label {
    color: var(--neu-mid) !important;
}
/* Engraved, even at 10px — which is under the size the deductibles week strip
   was excluded at, and the difference is the letterforms rather than the number.
   These are UPPERCASE at 600 with 0.05em tracking: caps fill the em so there is
   a full-height stem for the groove to run down, and the tracking keeps a 1px
   offset off the next glyph. The week strip is 9.5px mixed-case tabular figures
   packed tight, where the same offset lands on its neighbour.
   Opacity on the non-winners fades the shadow with the text, which is right
   here — the whole label is meant to recede together. */
body.neu-mode .vbar-pill .vbar-label {
    text-shadow: var(--neu-engrave);
}
/* Everything that isn't the winner sits back a little, so the contrast comes
   from both directions rather than only from raising one bar. */
body.neu-mode .vbar-pill:not(.is-max) .vbar-amount,
body.neu-mode .vbar-pill:not(.is-max) .vbar-label {
    opacity: .72;
}
body.neu-mode .vbar-track,
body.neu-mode .vbar-pill .vbar-amount,
body.neu-mode .vbar-pill .vbar-label {
    transition: box-shadow .25s ease, transform .25s ease, opacity .25s ease;
}

/* ── Calendar ───────────────────────────────────────────────────────────── */
body.neu-mode .cal-day {
    background: var(--neu-bg) !important;
    border: none !important;
    border-radius: 14px !important;
    color: var(--neu-mid) !important;
    box-shadow: var(--neu-out-sm) !important;

    /* Cut into the tile — the inverse of the selected day's raised digit below.
       Shared with every other small figure in the theme; see --neu-engrave. */
    text-shadow: var(--neu-engrave) !important;

    /* index.css transitions transform but not box-shadow — fine where depth is
       a flat blue fill, wrong here, where the shadow IS the depth. Without this
       the tile snaps between raised and sunken while the scale glides, and the
       press lands as a flicker. Matched to the .icon-btn timings above. */
    transition: box-shadow .16s ease, color .16s ease,
                transform .12s ease, background .16s ease !important;
}
/* Hovering LIFTS. The pressed state below is only as obvious as the raised
   state it is measured against, and a grid of 35 identical tiles gives the eye
   no reference until one of them moves. */
body.neu-mode .cal-day:hover {
    color: var(--neu-ink) !important;
    box-shadow: 7px 7px 14px var(--neu-dark), -7px -7px 14px var(--neu-light) !important;
}

/* ── The selected day ──
   This was blue text and --neu-in-sm, and it did not read as pressed. Three
   things were wrong, and the shadow was the least of them:

   1. index.css gives .cal-day.selected `transform: scale(1.12)`. Nothing here
      reset it, so the tile the theme was trying to sink was simultaneously
      swelling 12% OUT of the grid. Now it sinks — under 1, not over.
   2. --neu-in-sm (3px) is shallower than the --neu-out-sm (5px) every
      neighbouring tile wears, so the "pressed" tile carried the LEAST shadow
      on the board. --neu-in-deep out-shadows the raised state instead.
   3. No tonal change. A well catches less light; --neu-sunk supplies that.

   :hover is folded in so the tile does not pop back out when the pointer
   crosses it — index.css escalates the selected day to scale(1.14) on hover,
   which would undo the whole effect at exactly the moment it is being read. */
body.neu-mode .cal-day.selected,
body.neu-mode .cal-day.active,
body.neu-mode .cal-day.selected:hover,
body.neu-mode .cal-day.active:hover {
    background: var(--neu-sunk) !important;
    color: var(--neu-blue) !important;
    box-shadow: var(--neu-in-deep) !important;
    transform: scale(0.97) !important;

    /* The tile sinks; the DIGIT rises out of it. Two opposed light cues on one
       control is the whole trick of soft UI, and it is what makes the state
       unmistakable rather than merely darker.

       Poppins, not the grid's DM Sans: index.php loads DM Sans at 300/400/500
       only, so a 700 here would be synthesised by the browser — smeared
       outlines, exactly the mush this treatment is trying to avoid. Poppins is
       the theme's figure face and IS loaded at 700. It is the same font the big
       display numbers already wear, so the selected day joins that family
       instead of inventing a fourth weight for itself. */
    font-family: var(--neu-figure) !important;
    font-weight: 700 !important;
    /* 12px is the grid's size; this is the one tile allowed to break it. Sized
       against the SHRUNKEN tile, not the flat one — scale(0.97) takes a little
       back, so the rendered digit lands near 20.4px, close to double its
       neighbours. Two digits measure roughly 28px here, so on a narrow viewport
       where the tiles drop under ~44px the number starts crowding the inset
       shadow that frames it. Deliberate: legibility was the point. */
    font-size: 21px !important;

    /* Highlight up-left, shadow down-right. Reversing them would sink the digit
       into the well and cancel the effect — this is the one figure in the theme
       that rises while its surface falls. */
    text-shadow: var(--neu-raise) !important;
}
/* ── Spillover days from the neighbouring months ──
   index.css already fades these, and the renderer never binds a click to them
   (`.cal-day:not(.other-month)`), so they have always been inert. But
   `body.neu-mode .cal-day` repaints EVERY tile, colour and shadow both, so they
   arrived here wearing the same raised plate as a live day — and in soft UI a
   raised surface means "press me". They were the one thing on the grid that
   could not be pressed, dressed as the one thing that could.

   Flat, transparent, faint: the number is printed on the card rather than
   standing on a plate of its own, which is the same thing .cal-day.empty below
   says. They stay legible on purpose — seeing `1` under SAT tells you the month
   starts on a Saturday without counting columns.

   :hover is in the selector, not left to inheritance. It has to out-rank
   `body.neu-mode .cal-day:hover` above, which would otherwise lift a dead cell
   like a button under the pointer. */
body.neu-mode .cal-day.other-month,
body.neu-mode .cal-day.other-month:hover {
    background: transparent !important;
    box-shadow: none !important;
    color: var(--neu-faint) !important;
    transform: none !important;
    cursor: default !important;
    /* No engraving. There is no plate here to cut into — these numbers sit on
       the card itself, and a groove floating on the background would claim a
       surface that was removed two declarations up. */
    text-shadow: none !important;
}
body.neu-mode .cal-day.empty { box-shadow: none !important; }

/* ── Tables ─────────────────────────────────────────────────────────────── */
body.neu-mode table { border-collapse: separate !important; border-spacing: 0 8px !important; }
body.neu-mode thead th {
    background: transparent !important;
    border: none !important;
    color: var(--neu-soft) !important;
    font-weight: 600;
}
/* Rows use a VERTICAL-only wash, unlike the cards.

   Two constraints force it. Backgrounds have to stay on the cells, because
   border-radius on a <tr> is ignored in Chrome and the row's corners come from
   the first and last cell. But a cell-painted gradient restarts at every column,
   so anything with a horizontal component would repeat across the row like a
   strip of separate panels. A purely vertical gradient is identical in every
   cell of the same height, so it tiles invisibly and the row reads as one
   continuous surface. */
body.neu-mode tbody tr { background: transparent !important; }
body.neu-mode tbody td {
    background: var(--neu-row-bg) !important;
    border: none !important;
    color: var(--neu-mid) !important;
}

/* Everything in the table is cut into the row — letters as well as figures, so
   a name and the amount beside it sit at the same depth. text-shadow inherits,
   so one declaration on the cell reaches the nested spans and divs the rows are
   built from, and the figures list above becomes a no-op here rather than a
   conflict: both resolve to --neu-engrave. */
body.neu-mode thead th,
body.neu-mode tbody td {
    text-shadow: var(--neu-engrave);
}

/* …except anything wearing its own colour. Engraving reads as a groove only
   when the ink is darker than the surface behind it; on a coloured pill with
   white text — the MS grade badges, brand tags, status chips on the repairs and
   parts tables — the same highlight lands white-on-white and just smears the
   label. Matched on the class SUBSTRING deliberately: these pills are named a
   dozen different ways across the app, and the next one to be added should opt
   out by default rather than by being remembered. */
body.neu-mode thead th [class*="badge"],
body.neu-mode thead th [class*="chip"],
body.neu-mode thead th [class*="pill"],
body.neu-mode thead th [class*="tag"],
body.neu-mode tbody td [class*="badge"],
body.neu-mode tbody td [class*="chip"],
body.neu-mode tbody td [class*="pill"],
body.neu-mode tbody td [class*="tag"] {
    text-shadow: none;
}
/* ── Seller avatars, sunk into the surface ──
   Both places a person's face appears: the Top Sellers / payments list and the
   last column of the sales table. Photo and initials-circle get identical
   treatment because they alternate row to row in the same column, and a
   depression next to a plain disc reads as a rendering fault.

   --neu-sunk-rim rather than an inset shadow — see the token for why an <img>
   cannot take one. The border on .rep-avatar goes: at this size a 1px blue ring
   competes with the rim and the two together read as a sticker, not a socket. */
body.neu-mode .seller-avatar,
body.neu-mode .seller-avatar-placeholder,
body.neu-mode .rep-avatar,
body.neu-mode .rep-avatar-img {
    box-shadow: var(--neu-sunk-rim) !important;
    border: none !important;
}
/* The initials circles are CSS-drawn, so they can also take a real inner
   shadow on top of the rim — the photo cannot, and this is the one difference
   between them that improves the illusion rather than breaking it. */
body.neu-mode .seller-avatar-placeholder,
body.neu-mode .rep-avatar {
    background: var(--neu-sunk) !important;
    /* --neu-mid, not the fainter --neu-soft the recess would suggest. These are
       two 11px letters standing in for a person; --neu-soft on --neu-sunk is
       about 2.4:1, which loses the initials to the socket. */
    color: var(--neu-mid) !important;
    text-shadow: var(--neu-engrave);
}

/* ── Product thumbnails, sunk to match the avatars ──
   Same circular socket, same rim. The wrapper carries it rather than the <img>
   so the photo and the fallback icon sit in ONE well — otherwise a row with a
   missing picture would show a socket of a different size from the row above. */
body.neu-mode .product-img-wrap {
    border-radius: 50%;
    background: var(--neu-sunk);
    box-shadow: var(--neu-sunk-rim);
}
body.neu-mode .product-img { box-shadow: none !important; }
body.neu-mode .product-img-fallback { color: var(--neu-soft); }

/* ── Pay icons ──
   These are transparent PNGs, not circular photos, so they cannot take the rim
   the way an avatar does: a box-shadow follows the element's BOX, and on a
   card-shaped glyph with empty corners that draws a rectangle of shade around
   a picture of a card.

   Given a socket instead. The icon keeps its 26px and gains 4px of padding
   inside a 34px well, which lands within a pixel of the seller avatars beside
   it — the column reads as one row of sunken discs rather than two sizes. */
/* RAISED, not sunk. These sat in sockets like the thumbnail and the seller
   avatar either side of them, which made the whole row read as one recessed
   strip and left the payment mark — the only cell carrying a decision — with no
   more emphasis than the furniture. Lifting it out is what makes the column
   scannable: the eye finds the discs that stand up.

   Ground colour rather than --neu-sunk underneath, because a raised disc has to
   be the same tone as the surface it rises from; keeping the darker sunk fill
   would read as a button with a dirty face. */
body.neu-mode .pay-type-ico {
    width: 34px !important;
    height: 34px !important;
    padding: 4px;
    box-sizing: border-box;
    border-radius: 50%;
    background: var(--neu-bg);
    box-shadow: var(--neu-raise-sm);
}
/* The em dash for an unrecorded payment gets the same well, so the column keeps
   its rhythm where the data is missing. It is the one cell that should stay
   quiet, hence no engraving on top. */
/* The em dash rises with them, so the column keeps one rhythm where the payment
   was never recorded. It stays the quiet one through its colour, not by sitting
   at a different depth from its neighbours. */
body.neu-mode .pay-type-none {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--neu-bg);
    box-shadow: var(--neu-raise-sm);
    text-shadow: none;
}

/* Row shadow goes on the first and last cell only, so the pill doesn't get a
   seam at every column boundary. */
body.neu-mode tbody td:first-child { border-radius: 16px 0 0 16px; box-shadow: -5px 5px 11px var(--neu-dark), -5px -5px 11px var(--neu-light); }
body.neu-mode tbody td:last-child  { border-radius: 0 16px 16px 0; box-shadow:  5px 5px 11px var(--neu-dark),  5px -5px 11px var(--neu-light); }

/* ── Parts Inventory: flat rows ─────────────────────────────────────────────
   The rules above give every table row a raised pill: gradient fill plus a
   shadow on the first and last cell. On the dashboard that is the point — a
   handful of rows reading as physical objects. On Parts Inventory it is 250
   rows of it, each already carrying a thumbnail, a SKU field, a brand chip, a
   stock pill, three figures and a profit badge. The pill under all that is one
   layer too many, so this table opts out and the rest of the app keeps it.

   Scoped by .parts-table, which lifts specificity from (0,2,3) to (0,3,3) and
   wins on merit — no !important needed except where the rule being beaten used
   it first.

   Flat, but NOT the same value as the ground: at --neu-bg the rows would
   dissolve into the page. One step lighter keeps the 8px border-spacing
   reading as a gap between rows rather than as nothing at all. */
body.neu-mode .parts-table tbody td {
    background: #edf1f9 !important;
}
/* ── Stock pill on the repair-sale cards ────────────────────────────────────
   Engraved, but keeping its OWN colour rather than dropping to the body grey.
   The usual objection to engraving coloured text is that a light shadow under
   a saturated fill reads as bad printing rather than depth — that holds for
   mid-tone colour, but these two are deliberately dark (green-800, red-800).
   At that weight the highlight still reads as a groove, and in-stock vs
   check-inventory stays legible at a glance instead of relying on the ring
   alone. No `color` here at all, so repairs.css keeps ownership of it. */
/* The price stands PROUD of the card while the labels around it are cut into
   it — the one figure on the card that rises. Nothing here touches colour: the
   blue-to-orange gradient is left exactly as it is, and only the relief is
   added. Hence the filter form; see --neu-raise-filter for why a text-shadow
   cannot be used on this element. */
body.neu-mode .product-card .product-price {
    filter: var(--neu-raise-filter);
}

/* The part name, cut into the card. */
body.neu-mode .product-name {
    text-shadow: var(--neu-engrave);
}

/* The quality grade KEEPS its coloured fill, so it cannot use --neu-engrave:
   that token is a light shadow for dark text on a light surface, and under
   white text on a saturated chip it has nothing to bite on — it just softens
   the letters.
 *
 * Inverted for light-on-dark instead. Dark up-left is the shadow cast INTO the
 * groove; the faint light edge below-right is its lit lower lip. Same light
 * source as every other engraved element, read against a dark ground.
 *
 * The chip's own drop shadow is swapped for an inset one so the pill sits in a
 * well rather than floating above the card — engraved has to mean the object
 * as well as the letters, or it reads as a raised badge with odd text. The
 * outer 1px light line along the bottom is what sells the cut edge. */
body.neu-mode .part-grade {
    text-shadow: -1px -1px 1px rgba(0, 0, 0, 0.45),
                  0   1px 1px rgba(255, 255, 255, 0.22);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.42),
                0 1px 0 rgba(255, 255, 255, 0.55) !important;
}

body.neu-mode .stock-badge {
    text-shadow: var(--neu-engrave);
    background: transparent !important;
}

body.neu-mode .parts-table tbody td:first-child,
body.neu-mode .parts-table tbody td:last-child {
    box-shadow: none;
}

/* ── Theme switcher itself ──────────────────────────────────────────────── */
body.neu-mode .emb-seg {
    background: var(--neu-bg) !important;
    border: none !important;
    border-radius: 999px !important;
    box-shadow: var(--neu-in-sm) !important;
}
body.neu-mode .emb-seg-btn {
    background: transparent !important;
    border: none !important;
    color: var(--neu-soft) !important;
    border-radius: 999px !important;
    box-shadow: none !important;
}
body.neu-mode .emb-seg-btn.on {
    color: var(--neu-ink) !important;
    background: var(--neu-bg) !important;
    box-shadow: var(--neu-out-sm) !important;
}

/* ── Brand tabs on the repair-sale toolbar ──────────────────────────────────
   The same three values the theme switcher uses, for the same reason: the track
   is a shallow well and the selected segment is the one thing raised out of it.
   Borrowed rather than invented so the two segmented controls on this app read
   as one component with two uses. */
/* RAISED slab, matching the reference: the control stands off the page and the
   selected segment stands off the control. --neu-out-sm is the same lift the
   raised cards use, so it belongs to the theme rather than being a one-off. */
body.neu-mode .mp-seg {
    background: var(--neu-bg) !important;
    box-shadow: var(--neu-out-sm) !important;
}
body.neu-mode .mp-tab {
    background: transparent !important;
    box-shadow: none !important;
    color: var(--neu-soft) !important;
}
/* The selected pill is LIGHTER than the slab, not just lifted — that contrast
   is what makes it read as selected in the reference. --neu-light is the
   theme's own highlight, so it stays in palette. */
body.neu-mode .mp-tab.open,
body.neu-mode .mp-tab.chosen {
    background: var(--neu-light) !important;
    box-shadow: var(--neu-out-sm) !important;
    color: var(--neu-ink) !important;
}

/* All three labels cut into the control, selected or not. The text-shadow form
   rather than the filter one: these are plain characters with a solid colour,
   so the shadow can sit behind them — the filter form exists for glyphs whose
   colour comes from a background, which is not the case here.

   Deliberately NOT on .mp-tab itself: text-shadow inherits, and on the tab it
   would also reach the brand logos' alt text and the generic SVG glyph, where a
   light shadow under an outline shape reads as a printing fault rather than a
   groove. The label span is the only thing that should carry it. */
body.neu-mode .mp-tab-label {
    text-shadow: var(--neu-engrave);
}

/* ── The checkout stepper ───────────────────────────────────────────────────
   Labels cut into the panel like every other small label in the theme, and the
   discs sit in it rather than on it — a raised disc here would compete with the
   step panels below, which are the things you actually press.

   The glyph gets the FILTER form of the engrave, not text-shadow: these are
   stroked SVG paths, and text-shadow does not apply to them at all. That is
   what --neu-engrave-filter exists for. */
body.neu-mode .co-chip-label {
    text-shadow: var(--neu-engrave);
}
body.neu-mode .co-chip-num {
    box-shadow: var(--neu-in-sm);
}
body.neu-mode .co-chip-num svg {
    filter: var(--neu-engrave-filter);
}

/* Current and done are deliberately NOT overridden here.
   They carry a lit, layered treatment of their own — gradient face, white
   catch-light, coloured shadow cast below — and restating box-shadow in this
   file would wipe all of it, since `body.neu-mode .co-chip.active …` (0,4,1)
   outranks the page's (0,3,0). The pending disc above still gets the engrave,
   which is the right read: not-yet-reached belongs to the surface, where you
   are and where you have been stand out of it.

   The glyph is the one thing that still needs a hand. The engrave filter is
   mixed for dark ink on a light ground; over the blue face it muddies a white
   stroke, so the lit disc gets a plain shadow underneath instead. */
body.neu-mode .co-chip.active .co-chip-num svg,
body.neu-mode .co-chip.done.active .co-chip-num svg {
    filter: drop-shadow(0 1px 1px rgba(10, 36, 66, .35));
}
body.neu-mode .co-chip.done .co-chip-num svg {
    filter: drop-shadow(0 1px 0 rgba(255, 255, 255, .9));
}
/* The connector is a groove cut in the surface; the green fills the groove. */
body.neu-mode .co-chip-line {
    box-shadow: inset 0 1px 2px rgba(63, 74, 86, .20);
}

/* ── Part photos, cut into the card ─────────────────────────────────────────
   An inset shadow paints inside the border box, above the background but BELOW
   the content — so on an <img> it is normally invisible, hidden under the
   picture. It works here only because .product-card img already carries 5px of
   padding: the groove renders in that ring, around the photo rather than under
   it. Raised to 8px so the shadow has room to read as a bevel rather than a
   dark line.

   The floor stays near-white. Plenty of part photos are transparent PNGs, and
   dropping --neu-sunk in behind them would put a grey box round every one. */
/* RAISED now, not sunk. The groove read as a hole cut in the card, which put
   the one thing you are trying to identify at the furthest point from the eye.
   A tile sitting on the surface brings it forward instead.

   The floor stays near-white: plenty of part photos are transparent PNGs, and
   dropping the theme's ground in behind them would put a grey box round every
   one. */
body.neu-mode .product-card .part-photo {
    padding: 10px !important;
    background: #ffffff !important;
    border-radius: 16px !important;
    box-shadow: var(--neu-out-sm) !important;
}
body.neu-mode .product-card:hover .part-photo {
    box-shadow: 7px 7px 14px var(--neu-dark), -7px -7px 14px var(--neu-light) !important;
}

/* ── Payment status switch panel ────────────────────────────────────────────
   The <button> here is a bare container — label, key, lamp — and the generic
   rules near the top of this file would paint --neu-sunk and a deep inset onto
   it, drawing a pill around all three. Four classes plus a type, so it beats
   `body.neu-mode .status-pill-btn.active` (0,3,1) and the page's own (0,2,0).

   The key and the lamp keep the page's treatment: the key is already a soft
   raised slab that presses in when chosen, which IS this theme's language, and
   the lamp is the one deliberately saturated thing in the control. */
body.neu-mode .co-status-group .status-pill-btn,
body.neu-mode .co-status-group .status-pill-btn:hover,
body.neu-mode .co-status-group .status-pill-btn.active,
body.neu-mode .co-status-group .status-pill-btn.active:hover {
    background: none !important;
    border-color: transparent !important;
    box-shadow: none !important;
    color: var(--neu-mid) !important;
}
body.neu-mode .co-status-group .spb-label {
    text-shadow: var(--neu-engrave);
}
/* Engraved into the key's face, the same filter form the stepper glyphs use —
   text-shadow does nothing to a stroked path. */
body.neu-mode .co-status-group .spb-key svg {
    filter: var(--neu-engrave-filter);
}

/* ── Step panel headers ─────────────────────────────────────────────────────
   The same treatment one level down, so the rail above and the panels below
   read as one control rather than two that happen to share colours.

   Only the PENDING badge is engraved, matching the discs: not-yet-reached
   belongs to the surface, open and done stand out of it and carry their own
   lit shadows from the page. Restating box-shadow for those two here would
   outrank the page (0,4,1 against 0,3,0) and flatten them — the same trap the
   discs above are commented for. */
body.neu-mode .co-head-title,
body.neu-mode .co-head-check {
    text-shadow: var(--neu-engrave);
}
body.neu-mode .co-head-num {
    box-shadow: var(--neu-in-sm);
}
/* Glyphs, not numerals, so these are drop-shadow filters rather than
   text-shadow — text-shadow does not apply to a stroked SVG path at all. */
body.neu-mode .co-head-num svg {
    filter: var(--neu-engrave-filter);
}
/* The glyph on the lit badge is white on blue; the engrave is mixed for dark
   ink on a light ground and only muddies it there. */
body.neu-mode .co-step.open .co-head-num svg,
body.neu-mode .co-step.done.open .co-head-num svg {
    filter: drop-shadow(0 1px 1px rgba(10, 36, 66, .35));
}
body.neu-mode .co-step.done .co-head-num svg {
    filter: drop-shadow(0 1px 0 rgba(255, 255, 255, .9));
}

/* ── The model panel ────────────────────────────────────────────────────────
   The panel inherits --glass-bg, which this theme aliases to --neu-bg — the
   exact colour of the page behind it. A dropped panel that shares the ground's
   tone relies on its shadow alone to separate, and over a busy grid of cards
   that is not enough. Lifting it toward the highlight (not to it: pure white
   is a different material and would read as a system menu, not part of the
   app) gives it its own plane while staying in palette.

   No !important on the background any more: the page now paints a graded face
   here, and forcing a flat colour over it was the difference between a panel
   and a rectangle. The ramp below is the same idea in this theme's palette —
   lifted off --neu-bg at the top, settling back toward it at the foot. */
body.neu-mode .mp-panel {
    background: linear-gradient(180deg, #f7fafe 0%, #eef3fa 55%, #e8eef7 100%);
    border-color: rgba(255, 255, 255, 0.9) !important;
    box-shadow: 0 2px 6px rgba(63, 74, 86, .10),
                0 26px 60px -14px rgba(63, 74, 86, .28),
                inset 0 1px 0 rgba(255, 255, 255, 1);
}
/* Model names cut into that plane, same as every other label in the theme.
   text-shadow rather than the filter form for the same reason as .mp-tab-label
   above: these are plain characters in a solid colour, so the shadow can sit
   behind them. It carries to .picked too — a blue name is still solid ink. */
body.neu-mode .mp-model {
    text-shadow: var(--neu-engrave);
}
/* The hover wash was mixed for the darker panel and barely shows on the lighter
   one. Pressed-in instead, which is what this theme uses for "you are on it"
   everywhere else. */
body.neu-mode .mp-model:hover {
    /* Pressed into the panel AND tinted. The inset alone was the theme's own
       language but said nothing about which control you were on in a list of 37
       near-identical names; the tint carries that, the inset carries the theme. */
    background: linear-gradient(90deg, rgba(26, 95, 168, .09), rgba(26, 95, 168, .02));
    box-shadow: var(--neu-in-sm);
}
body.neu-mode .mp-model.picked {
    box-shadow: var(--neu-in-sm);
}

/* ── Status colours, muted to sit on a soft ground ──────────────────────── */
body.neu-mode .stock-good,   body.neu-mode .profit-positive { background: rgba(47, 208, 127, .13) !important; color: #1f8a56 !important; }
body.neu-mode .stock-out,    body.neu-mode .profit-negative { background: rgba(224, 95, 143, .13) !important; color: #b04168 !important; }
body.neu-mode .stock-low                                    { background: rgba(240, 180, 41, .15) !important; color: #92702a !important; }

/* ── Payments hero panel ────────────────────────────────────────────────────
   The hero was drawn for the dark analytics design, where the Card series is a
   near-white cream (#F4EFE9) and the chart furniture is white at 5–18% alpha.
   All of that disappears on a light ground.

   Targeted by ATTRIBUTE VALUE rather than by element id. The colours are baked
   into the SVG as presentation attributes by the render JS, so [stroke="#F4EFE9"]
   catches exactly the cream parts — line, gauge arc, needle, donut — wherever
   they appear, and keeps working if a chart is added or reordered. Chasing
   #heroSpark1 / #heroDist1 by index would break the first time one moves.

   CSS properties beat presentation attributes, so this needs no !important
   except where the renderer writes an inline style. */
body.neu-mode [stroke="#F4EFE9"] { stroke: #8FA0B8 !important; }
body.neu-mode [fill="#F4EFE9"]   { fill:   #8FA0B8 !important; }
body.neu-mode [stop-color="#F4EFE9"] { stop-color: #8FA0B8 !important; }

/* The hero card carries a ::before layer from dashboard.css that paints two
   orange glows, bottom-left and top-right — the dark design's warm light. The
   theme repaints the card beneath it but had left the layer on, so both
   corners kept a peach cast after every other orange was gone. Off. */
body.neu-mode .hero-card::before { display: none; }

/* Cash: the theme's blue, not the dark design's orange — which was the one
   warm thing on a cool card. Cash is the headline of the gauge, so it wears
   the primary accent, the same blue the nav gives the current page. Deep at
   the base and sky at the tip, so the arc still reads as lit the way the
   orange did. Card stays the slate above: blue against slate is the pairing
   the whole theme is built on. */
body.neu-mode [stop-color="#C2611F"] { stop-color: #3B6FD4 !important; }
body.neu-mode [stop-color="#F5B45C"] { stop-color: #8FB4F7 !important; }
/* The Cash sparkline and the donut draw with the series colour, and they have
   to agree with the arc or the chart argues with its own headline. The peak
   dot's glow is an inline style, so it needs the !important to be overruled. */
body.neu-mode [stroke="#E8873A"]     { stroke: #4F82E6 !important; }
body.neu-mode [fill="#E8873A"]       { fill:   #4F82E6 !important; filter: drop-shadow(0 0 4px #4F82E6) !important; }
body.neu-mode [stop-color="#E8873A"] { stop-color: #4F82E6 !important; }
/* Transactions was already this blue and would now collide with Cash; it takes
   the theme's green instead. Three hues, all theme tokens: blue cash, slate
   card, green transactions. */
body.neu-mode [stroke="#5B8DEF"]     { stroke: #2FB877 !important; }
body.neu-mode [fill="#5B8DEF"]       { fill:   #2FB877 !important; filter: drop-shadow(0 0 4px #2FB877) !important; }
body.neu-mode [stop-color="#5B8DEF"] { stop-color: #2FB877 !important; }

/* Chart furniture: axes, gridlines and gauge tracks were white-on-dark. */
body.neu-mode [stroke^="rgba(255,255,255"] { stroke: rgba(63, 74, 86, 0.13) !important; }

/* The Card figure and its label sat in the same cream. */
body.neu-mode .hero-spark-row:nth-child(2) .hero-spark-val,
body.neu-mode .hero-dist-cell:nth-child(2) .hero-dist-name {
    color: #6B7A90 !important;
}

/* Totals under the gauge and the donut percentages — light on dark by design,
   so they read as barely-there smudges here. */
body.neu-mode .hero-gfoot,
body.neu-mode .hero-gflab,
body.neu-mode .hero-dist-name,
body.neu-mode .hero-spark-name,
body.neu-mode .hero-spark-val,
body.neu-mode .hero-dots,
/* "Total Collected" and "Average Ticket" — .hero-gfval is #F4EFE9 in
   dashboard.css, which is the cream that vanishes here. */
body.neu-mode .hero-gfval {
    font-family: var(--neu-figure) !important;
    font-weight: 700 !important;
    letter-spacing: -0.02em !important;
    color: var(--neu-ink) !important;
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    body.neu-mode .hero-gfval {
        background: var(--neu-figure-grad) !important;
        -webkit-background-clip: text !important;
        background-clip: text !important;
        -webkit-text-fill-color: transparent !important;
        background-size: 100% 100% !important;
        background-repeat: no-repeat !important;
    }
}

/* The up/down arrows sit INSIDE .hero-gfval. -webkit-text-fill-color inherits,
   so without this they'd go transparent with the parent and be repainted by its
   grey ramp — silently losing the only colour that carries their meaning.
   Both darkened a step from the dark-theme originals to hold up on a light card. */
body.neu-mode .hero-gfval .hero-up {
    color: #3E9E68 !important;
    -webkit-text-fill-color: #3E9E68 !important;
}
body.neu-mode .hero-gfval .hero-down {
    color: #CE4A76 !important;
    -webkit-text-fill-color: #CE4A76 !important;
}

/* The divider above them was white at 9% — invisible on a light ground. */
body.neu-mode .hero-gfoot {
    border-top-color: rgba(63, 74, 86, 0.14) !important;
}

/* ── Under and inside the gauge ──
   The Cash / Card figures take the FILTER form, not text-shadow. They are
   gradient-filled by the @supports block near the top of this file, and a text
   shadow paints in the foreground — it would sit on top of that gradient as a
   smear across the digits rather than behind them.

   Applied to the row rather than to .hero-gval so the two labels beneath the
   figures are cut in by the same pass; they are inside it and a filter applies
   to the whole rendered subtree.

   .hero-gfval — "$1,213.41" and "$202.23" — is deliberately NOT here. It is in
   the raised headline list near the top of this file and keeps its extruded
   look; these two treatments are opposites and it must not receive both. */
body.neu-mode .hero-gauge-nums {
    filter: var(--neu-engrave-filter);
}
/* Their captions sit outside .hero-gfval, so plain text-shadow is enough. */
body.neu-mode .hero-gflab {
    text-shadow: var(--neu-engrave);
}
/* Sparkline captions — the name and value above each graph. One rule on the
   row covers both, and it cannot reach the <svg> beneath: that is a SIBLING of
   .hero-spark-top, not a child, so the graphs are left alone.
   Plain text-shadow, not the filter: unlike the gauge figures these are solid
   --neu-ink, never gradient-filled. */
body.neu-mode .hero-spark-top {
    text-shadow: var(--neu-engrave);
}

/* ── The sparkline channel ──
   The lines themselves are NOT sunk, deliberately. A 1.6px stroke with a 1px
   engrave offset gives a shadow nearly as wide as the line — a doubled blur,
   not a groove — and a filter would take the gradient area fill and the pulse
   dots with it. The surface underneath gets the depth instead, and the data
   keeps its own weight.

   Geometry lives in sparks() in index.php, which draws these with stroke:none
   so only this theme opts in. */
body.neu-mode .hero-spark-channel   { stroke: var(--neu-sunk) !important; }
body.neu-mode .hero-spark-groove-top { stroke: var(--neu-dark) !important; }
body.neu-mode .hero-spark-groove-bot { stroke: var(--neu-light) !important; }
/* The currency mark at the top of the dial. An SVG <text>, so it takes the
   filter form for the same reason the figures above do. */
body.neu-mode .hero-gauge-cur {
    filter: var(--neu-engrave-filter);
}

/* ── The gauge, cut into the card ──
   The track was white at 6%, which is the dark design's faint channel and does
   nothing on a light ground. Repainted as a groove: --neu-sunk for the tonal
   drop, and the same reversed shadow pair the avatars wear — dark up-left,
   light down-right — so the channel reads as carved rather than drawn.

   drop-shadow(), not box-shadow. This is a stroked SVG arc: box-shadow would
   trace the element's rectangular box, while a drop-shadow filter follows the
   rendered stroke, so the shade hugs the curve. It is the same reason the pay
   icons needed a socket instead of a rim.

   The value arcs are left flat on top. They are what SITS in the channel, and
   giving them their own depth would have the two fighting for the same light. */
body.neu-mode .hero-gauge-track {
    stroke: var(--neu-sunk) !important;
    filter: drop-shadow(-1.5px -1.5px 1.5px var(--neu-dark))
            drop-shadow( 1.5px  1.5px 1.5px var(--neu-light));
}
/* #F4EFE9 is the dark design's cream — a near-white triangle on a near-white
   card. It marks where the day's split falls, so it has to be visible. */
body.neu-mode .hero-gauge-needle {
    fill: var(--neu-soft) !important;
}

/* Today-in-context panel: same dark-design colours as the rest of the hero,
   so the same treatment applies. */
body.neu-mode .hero-vs-lab,
body.neu-mode .hero-vs-sub,
body.neu-mode .hero-vs-row,
body.neu-mode .hero-vs-v { color: var(--neu-mid) !important; }
body.neu-mode .hero-vs-k { color: var(--neu-ink) !important; }
body.neu-mode .hero-vs-rows { border-top-color: rgba(63, 74, 86, 0.14) !important; }
body.neu-mode .hero-vs-row  { border-bottom-color: rgba(63, 74, 86, 0.09) !important; }

/* The delta gets the display-figure TREATMENT but keeps its own colour.
   Deliberately absent from the @supports gradient block: the slate ramp would
   overwrite the green/red, and here the colour IS the information — up or down.
   So it takes the face, the tracking and the raise, but not the fill.
   (The house standard says add a figure to all three lists; a figure whose
   colour carries meaning is the exception, and this is it.) */
body.neu-mode .hero-vs-delta {
    font-family: var(--neu-figure) !important;
    font-weight: 700 !important;
    letter-spacing: -0.02em !important;
    font-variant-numeric: normal;
    color: var(--neu-soft) !important;   /* neutral state only */
}
body.neu-mode .hero-vs-delta.is-up   { color: #3E9E68 !important; }
body.neu-mode .hero-vs-delta.is-down { color: #CE4A76 !important; }

/* Everything in the context panel, cut in like the rest of the theme.
   .hero-vs-row is enough for its three lines — the bare <span> label, .hero-vs-k
   and .hero-vs-v all inherit from it.

   .hero-vs-delta is POINTEDLY absent. It is the one raised figure in this panel
   and it gets its depth from filter: drop-shadow() above, because its fill
   carries meaning (green up, red down) and a text-shadow would sit in the
   foreground and smear across the glyphs. Engraving the container instead of
   these children would have inherited straight into it. */
body.neu-mode .hero-vs-lab,
body.neu-mode .hero-vs-sub,
body.neu-mode .hero-vs-row,
body.neu-mode .hero-top-lab,
body.neu-mode .hero-top-name,
body.neu-mode .hero-top-amt {
    text-shadow: var(--neu-engrave);
}

/* ── The two product thumbnails, sunk ──
   A rounded SQUARE well, not the circle the avatars get: these are product
   photos on `object-fit: contain`, so a phone letterboxes tall and a part
   letterboxes wide. A circular socket would cut the corners off both.

   3px of padding inside the existing 34px box, so the well shows AROUND the
   photo rather than behind it. The 34px is load-bearing — .hero-top-row's grid
   is `34px 1fr auto` and the two have to stay in step — so the frame comes out
   of the photo's size rather than the column's. */
body.neu-mode .hero-top-icowrap {
    border-radius: 10px;
    background: var(--neu-sunk);
    box-shadow: var(--neu-sunk-rim);
    padding: 3px;
    box-sizing: border-box;
    overflow: hidden;
}

/* Top phone / top repair rows */
body.neu-mode .hero-top-rows { border-top-color: rgba(63, 74, 86, 0.14) !important; }
body.neu-mode .hero-top-ico,
body.neu-mode .hero-top-lab  { color: var(--neu-soft) !important; }
body.neu-mode .hero-top-name,
body.neu-mode .hero-top-amt  { color: var(--neu-ink) !important; }

/* Scrollbars, so the soft ground isn't cut by a hard grey strip. */
body.neu-mode ::-webkit-scrollbar { width: 11px; height: 11px; }
body.neu-mode ::-webkit-scrollbar-track { background: var(--neu-bg); }
body.neu-mode ::-webkit-scrollbar-thumb {
    background: var(--neu-bg);
    border-radius: 999px;
    box-shadow: var(--neu-in-sm);
}

/* ═══════════════════════════════════════════════════════════════════════════
   ACTIVE REPAIRS  (repairs/active_repairs.php)

   The page already inherits everything generic above — ground, cards, buttons,
   tables, inputs. What it needs is its own components given the same three
   depths the dashboard uses, so the two pages read as one product:

       RAISED    the ticket card, the current step, headline figures
       ENGRAVED  every label and small figure
       SUNK      avatars, photos, and steps not reached yet

   Kept in one block rather than scattered through activerepairs.css because
   that file has to keep working in the five other themes.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── The ticket card ──
   activerepairs.css gives this a four-part shadow built for a darker surface:
   two black drops at 22% and 10%, plus two inset washes. On this ground that
   reads as a bruise. Replaced wholesale with the theme's own extrusion. */
body.neu-mode .repair-card {
    background: var(--neu-card-bg) !important;
    border: none !important;
    box-shadow: var(--neu-out) !important;
}
body.neu-mode .repair-card:hover {
    box-shadow: 11px 11px 24px var(--neu-dark), -11px -11px 24px var(--neu-light) !important;
}

/* ── Progress stepper ──
   The clearest place on this page for depth to carry meaning: a step you have
   not reached is a hole, the one you are on stands out of the surface. That is
   readable across the room in a way two greys are not.

   .rp-upcoming keeps its own pale fill and takes an inset — a well with
   something in it. .rp-active and .rp-done keep their accent fill (the colour
   IS the state) and take the raise instead, so the shadow adds depth without
   touching what the colour says. */
body.neu-mode .rp-upcoming .rp-circle {
    background: var(--neu-sunk) !important;
    color: var(--neu-soft) !important;
    border: none !important;
    box-shadow: var(--neu-in-sm) !important;
}
body.neu-mode .rp-done .rp-circle,
body.neu-mode .rp-active .rp-circle {
    border: none !important;
    box-shadow:
        -2px -2px 4px rgba(255, 255, 255, 0.85),
        3px 3px 6px rgba(146, 162, 188, 0.55) !important;
}
/* The active step keeps its coloured halo AND the raise — the ring is the
   "you are here" marker and the shadow is the depth; losing either flattens it. */
body.neu-mode .rp-active .rp-circle {
    box-shadow:
        0 0 0 4px var(--rp-soft),
        -2px -2px 4px rgba(255, 255, 255, 0.85),
        4px 4px 8px rgba(146, 162, 188, 0.5) !important;
}
/* The connector is a channel the steps sit along, so it is cut in rather than
   drawn on — same reasoning as the sparkline baselines on the dashboard. */
body.neu-mode .rp-line {
    background: var(--neu-sunk) !important;
    box-shadow: inset 1px 1px 2px var(--neu-dark), inset -1px -1px 1px var(--neu-light) !important;
}
body.neu-mode .rp-label { text-shadow: var(--neu-engrave); }

/* ── Sourcing flag ("Mobile Sentrix · date") ──
   Keeps its provider colour, which is the whole point of the chip. Only the
   shadow changes: a flat drop reads as pasted on, a raise reads as part of the
   surface it labels. */
body.neu-mode .rp-source-flag {
    border: none !important;
    box-shadow:
        -1px -1px 2px rgba(255, 255, 255, 0.9),
        2px 2px 5px rgba(146, 162, 188, 0.45) !important;
}
body.neu-mode .rp-flag-name,
body.neu-mode .rp-flag-date { text-shadow: var(--neu-engrave); }

/* ── People and product photos ──
   Sunk, exactly as on the dashboard: --neu-sunk-rim, because an <img> cannot
   take an inset shadow — inner shadows paint below the element's content, so a
   photo covers them. See the token for the full note. */
body.neu-mode .soldby-avatar,
body.neu-mode .completed-img,
body.neu-mode .cl-item img {
    border: none !important;
    box-shadow: var(--neu-sunk-rim) !important;
}

/* ── The info panel (unlock / location / photos / notes) ──
   Left flat on purpose — no raise, no recess. It is the one region of the ticket
   that is mostly reference material, and a third depth here would give the card
   three tiers of panel stacked on a raised surface.

   FLAT, but pitched to the card rather than to the page.

   The customer-info area at the top of the ticket is not a panel — it is the
   card itself, on --neu-card-bg. That token is three layers deep (a white bloom
   top-left, a cool slate cast bottom, over a blue-grey ramp), so nothing FLAT can
   match it exactly; #eaf0f9 is the light end of its base ramp, which is the
   part of it this panel sits against.

   It was --neu-bg (#e4ebf5) — the page ground, a step cooler and darker than
   the card. Correct if the panel were a hole in the ticket, wrong now that it
   is meant to read as the same surface the customer name sits on.

   The edge is DASHED rather than solid. A solid rule would be the only hard
   line on a card built entirely from soft ones — but a dashed edge reads as a
   boundary you can see through, which is what this region is: a marked-off area
   of the same surface rather than a separate object placed on it. It also
   rhymes with the dashed Add-photo tile sitting inside it, at the same weight
   and colour, so the two read as one idea instead of two borrowings.

   The section rules INSIDE stay — they are what separate unlock from photos
   from notes — softened to the value the card dividers use. */
body.neu-mode .info-panel {
    /* The light end of --neu-card-bg's base ramp — see the note above. */
    background: #eaf0f9 !important;
    background-image: none !important;
    border: 1.5px dashed rgba(120, 140, 170, 0.42) !important;
}
body.neu-mode .info-panel > *:not(:last-child) {
    border-bottom-color: rgba(63, 74, 86, 0.10) !important;
}

/* ── The repair part photo ──
   Recessed, and that is a statement about what it IS. Nothing happens when you
   click it — it is evidence, not a control — and everywhere else in this theme
   raised means pressable. A raised photo would promise a click it does not
   deliver.

   The dashed border and its 2px of padding go with it: the well supplies the
   edge, and a dashed outline on top of a recess reads as a sticker stuck over a
   hole, the same thing that went wrong on the REP tag. The background goes too,
   since --neu-sunk is now doing that job. */
body.neu-mode .customer-avatar {
    border: none !important;
    padding: 0 !important;
    background: var(--neu-sunk) !important;
    box-shadow: var(--neu-sunk-rim) !important;
}

/* ── Pay status, and the device location control that shares its styling ──
   The pills go. Three bordered capsules for what is really one three-way switch
   drew four more edges into a header that already has a card border, a date and
   an order tag — and only one of the three was ever the answer.

   What replaces them is a strip of engraved options split by hairlines: the
   text is cut into the card, and the ACTIVE one is simply the one wearing its
   own status colour. Green Paid, red Pay on Pickup, gold Deposit — the same
   three this file already uses for the ticket total, so the header and the
   money agree without a legend.

   Every decoration is forced off with !important because the catch-all
   `body.neu-mode button:not(...)` is (0,3,2) — higher than this rule — and
   would otherwise re-issue the pill we are removing. !important beats
   specificity, which is the only reason this works.

   The radio dot stays. With the pill gone it is the one piece of chrome left
   saying these are controls rather than a printed status line. */
body.neu-mode .pay-radios { gap: 0 !important; }
body.neu-mode .pay-radio {
    background: transparent !important;
    background-image: none !important;
    border: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 3px 11px !important;
    text-shadow: var(--neu-engrave);
}
/* The divider. On the sibling selector so the first option has no leading rule
   — (0,3,1) beats the `border: none` above at (0,2,1), both being !important. */
body.neu-mode .pay-radio + .pay-radio {
    border-left: 1px solid rgba(63, 74, 86, 0.14) !important;
}
/* The outer edges lose their padding. .header-right right-aligns the label and
   this row against the same edge, but the padding above is what separates each
   option from its divider — so on the last option it also pushed the TEXT 11px
   inside the row's own right edge, leaving "Deposit" short of where PAY STATUS
   ended. The padding is only wanted BETWEEN options, never outside them. */
body.neu-mode .pay-radio:first-child { padding-left: 0 !important; }
body.neu-mode .pay-radio:last-child  { padding-right: 0 !important; }
body.neu-mode .pay-radio.selected {
    color: var(--pr) !important;
    font-weight: 700 !important;
}
/* Hover names the option you are about to choose, in the colour it would
   become — the pill used to do this with a tint. */
body.neu-mode .pay-radio:not(.selected):hover {
    color: var(--pr) !important;
}

/* ── Edit and Delete: the icons alone ──
   The plate goes. Two 30px pills for two 13px glyphs was more chrome than the
   actions warrant, and they sit at the corner of a card that is already raised
   — a raised control on a raised surface reads as a sticker.

   Everything is forced off with !important because THREE rules paint these:
   .card-corner-actions .icon-btn (0,2,0), the icon-btn-*:hover pair (0,2,0),
   and the catch-all body.neu-mode button:not(...) at (0,3,2) — higher than this
   rule. !important is what beats that last one, not specificity.

   Grey at rest, the action's own colour on hover. The SVGs are stroked in
   currentColor, so `color` alone drives them; the greys match the contact icons
   below so the whole corner reads as one family. Hover keeps the 1px lift from
   .icon-btn:hover, which is now the only motion left saying these are pressable.

   The glyphs go 13px -> 16px. Without a plate behind them a 13px icon floats in
   a 30px hit area looking like a mistake; the button keeps its 30px so the
   target does not shrink with the artwork. */
body.neu-mode .icon-btn-edit,
body.neu-mode .icon-btn-park,
body.neu-mode .icon-btn-eye,
body.neu-mode .icon-btn-delete {
    background: transparent !important;
    background-image: none !important;
    border: none !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    color: rgba(120, 132, 150, 0.55) !important;
    /* Cut into the card, like the contact icons below. The FILTER form, not
       text-shadow: these are stroked SVG paths, so there is no text to shadow —
       just an outline, which is what drop-shadow() traces.

       Carried through hover deliberately. The hover rules below override colour
       and nothing else, so the groove stays while the glyph changes colour: the
       icon lights up in place rather than climbing out of the surface. */
    filter: var(--neu-engrave-filter);
}
body.neu-mode .icon-btn-edit svg,
body.neu-mode .icon-btn-park svg,
body.neu-mode .icon-btn-eye svg,
body.neu-mode .icon-btn-delete svg {
    width: 16px !important;
    height: 16px !important;
}
body.neu-mode .icon-btn-edit:hover {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    color: var(--primary, #2563EB) !important;
}
body.neu-mode .icon-btn-delete:hover {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    color: var(--danger, #EF4444) !important;
}

/* ── Parts quality buttons (phoneinv Add/Edit modal) ───────────────────────
   OEM / Refurb / AM showed NO selected state in this theme. The clicks always
   worked — the cue was erased three times over by the catch-all above:

     catch-all  body.neu-mode button:not(…):not(…)      (0,3,2)
     the state  .part-qual button[data-q="OEM"].active  (0,3,1)

   It wins on background AND colour, and its `border: none` takes border-STYLE
   with it — so the page's coloured border-color had no style to render against
   and drew nothing at all. Aurora and embossed both carry an override for this
   pair; neumorphic never did. Third time this catch-all has cost a selected
   state, after the checkout pay/status buttons and the device-location picker.

   Unselected is RAISED, selected is PRESSED — the soft-UI way of saying "this
   one is chosen", and the same language the calendar and the pay-status pills
   use. The quality COLOUR is kept as a tint plus the label, because on this row
   the colour is the information: green OEM, amber Refurb, red AM. */
body.neu-mode .part-qual button {
    background: var(--neu-bg) !important;
    background-image: none !important;
    border: none !important;
    border-radius: 8px !important;
    box-shadow: var(--neu-out-sm) !important;
    color: var(--neu-soft) !important;
}
body.neu-mode .part-qual button:hover {
    color: var(--neu-mid) !important;
}
/* The press is on .active alone, so all three variants below inherit it and
   only have to say what colour they are. */
body.neu-mode .part-qual button.active {
    box-shadow: var(--neu-in-deep) !important;
}
body.neu-mode .part-qual button[data-q="OEM"].active {
    background: rgba(5, 150, 105, 0.16) !important;
    color: #047857 !important;
}
body.neu-mode .part-qual button[data-q="Refurb"].active {
    background: rgba(202, 138, 4, 0.18) !important;
    color: #a16207 !important;
}
body.neu-mode .part-qual button[data-q="AM"].active {
    background: rgba(220, 38, 38, 0.15) !important;
    color: #b91c1c !important;
}

/* ── Contact icons: email, SMS, WhatsApp, call log ──
   ENGRAVED, not raised, even though they are buttons — the one place on this
   page where that rule bends, and deliberately.

   These are CSS masks tinted a flat #7A8899, colourless at rest, with each
   one's brand colour arriving only on hover. That restraint is doing real work:
   raise them and four grey glyphs start competing with the two actual action
   buttons directly above. Cut in, they stay quiet until you go looking, and
   hover keeps the job it already has.

   The filter form, because there is no text here to take a text-shadow — just
   an alpha silhouette, which is exactly what drop-shadow() traces. */
body.neu-mode .cico {
    filter: var(--neu-engrave-filter);
}

/* ── Detail panels ──
   There are exactly two of these on a ticket and both are full-width surfaces:
   the progress panel (stepper, sourcing stamp, pickup and tracking marks) and
   the price breakdown. Both raised, so they read as panels sitting on the card
   rather than holes cut into it.

   This started as a recess with the progress panel overridden back out of it.
   That left the base rule matching nothing — the two are the only .detail-chip
   elements in the codebase — so the exception has been folded into the rule.

   --neu-out-sm, not --neu-out: these sit on a card that is already extruded,
   and the wide shadow would have the two competing instead of nesting. */
body.neu-mode .detail-chip {
    background: var(--neu-card-bg) !important;
    border: none !important;
    box-shadow: var(--neu-out-sm) !important;
}
body.neu-mode .detail-label,
body.neu-mode .detail-value,
body.neu-mode .rp-tech-name,
body.neu-mode .header-date,
body.neu-mode .card-row-identity { text-shadow: var(--neu-engrave); }

/* ── Customer name ──
   The headline of the ticket, so it takes the headline treatment: Poppins,
   raised, sized up from the 15px it shares with body copy.

   `text-shadow: none` is not tidying. .card-row-identity is engraved directly
   above and it WRAPS this element — text-shadow inherits, so without the reset
   the name would carry a groove and a raise at once and come out blurred.

   No colour. activerepairs.css paints it house blue with a literal fallback,
   and drop-shadow() shadows the glyph shape without caring what fills it. */
body.neu-mode .customer-name {
    font-family: var(--neu-figure) !important;
    font-weight: 700 !important;
    font-size: 17px !important;
    letter-spacing: 0.005em !important;
    text-shadow: none;
    filter:
        drop-shadow(-1px -1px 1px rgba(255, 255, 255, 0.95))
        drop-shadow(2px 2px 3px rgba(146, 162, 188, 0.55));
}

/* ── The REP order number ──
   A raised stub sitting on the ticket. Everything that gave the tag its
   identity is left alone — the dashed orange border, the faint orange fill, the
   monospace face — and only depth is added, so it lifts without becoming a
   different object.

   A tight shadow, not --neu-out-sm. That token is 5px at 11px blur, sized for
   panels; under a 10px tag it spreads well past the dashes and the border stops
   reading as the tag's edge. This one stays inside the outline it belongs to.

   The digits are ENGRAVED on the raised plate — a stamped stub rather than a
   printed one. That stacks the two treatments on one element, which the rest of
   this file avoids, and here it is the point: the tag lifts off the ticket and
   the number is pressed into the tag.

   It sits right at the size limit --neu-engrave is written for. At 10px
   monospace the groove is close to the stroke width, so if it ever reads as a
   blur rather than as depth, halve the dark side before touching anything
   else — that is the half doing the damage at this size. */
body.neu-mode .order-tag {
    box-shadow:
        -1px -1px 2px rgba(255, 255, 255, 0.9),
        2px 2px 4px rgba(146, 162, 188, 0.42) !important;
    padding: 4px 11px !important;
    text-shadow: var(--neu-engrave);
}

/* ── The part line: item name and its sourcing pill ──
   Both cut in. The name is a description and the pill is a status — neither is
   a control, and every other piece of read-only text on this ticket is already
   engraved, so these two were the last flat ones left on the card.

   The pill keeps its colour and its tint. render_source_pill() paints it inline
   per source — gold Ordering, blue Pickup, green In House — and those three
   match the sourcing flag on the stepper above. Only the groove is added.

   .order-summary-name carries the same pair in the printed breakdown, so it
   takes the same treatment rather than staying flat beside them. */
body.neu-mode .part-name,
body.neu-mode .source-pill,
body.neu-mode .order-summary-name {
    text-shadow: var(--neu-engrave);
}

/* ── Money ──
   Same split the house rules use everywhere: the line items are small figures
   and get the groove; the order total is a headline and gets the raise. */
body.neu-mode .price-row:not(.price-total):not(.price-balance) {
    text-shadow: var(--neu-engrave);
}

/* Total and Balance Due — the two figures on a ticket anyone actually looks
   for. Raised like the dashboard's headline numbers, and the :not() above keeps
   them out of the engrave: a groove and an extrusion on the same glyphs cancel
   into a blur.

   NO colour is set here, deliberately. activerepairs.css paints Total from the
   ticket's pay status — green Paid, red Pay on Pickup, gold Deposit — and keeps
   Balance Due red whatever the status says, because it is money still owed. An
   earlier version of this rule forced --neu-ink and silently threw all four of
   those meanings away. drop-shadow() shadows the glyph SHAPE and does not care
   what colour fills it, which is exactly why the raise can be added without
   touching the palette.

   The order-summary pair are the same two figures in the printed summary, so
   they get the same treatment rather than a second look. */
body.neu-mode .price-row.price-total,
body.neu-mode .price-row.price-balance,
body.neu-mode .osr-total .order-summary-price,
body.neu-mode .osr-balance .order-summary-price {
    /* Poppins — the same face the dashboard's headline figures wear, loaded at
       600/700 by the @import at the top of this file. */
    font-family: var(--neu-figure) !important;
    font-weight: 700 !important;
    letter-spacing: -0.02em !important;
    filter:
        drop-shadow(-1px -1px 1px rgba(255, 255, 255, 0.95))
        drop-shadow(2px 2px 3px rgba(146, 162, 188, 0.55));
}
/* Only the AMOUNT grows, not its label. Each of these rows is a caption and a
   figure side by side; scaling the row would take "Balance Due" up with the
   number and lose the size difference that makes the figure the thing you read
   first. .osr-*-price is already the amount on its own, so it takes the size
   directly. 15px -> 19px, in step with how the dashboard's headline figures
   out-size their captions. */
body.neu-mode .price-row.price-total span:last-child,
body.neu-mode .price-row.price-balance span:last-child,
body.neu-mode .osr-total .order-summary-price,
body.neu-mode .osr-balance .order-summary-price {
    font-size: 19px !important;
    line-height: 1.15;
}

/* ── Panels that sit on top of the page ──
   The call log, the order summary and every modal are surfaces above the card,
   so they take the wide extrusion rather than the tight one. */
body.neu-mode .cl-panel,
body.neu-mode .modal-content,
body.neu-mode .ulk-modal,
body.neu-mode .trk-modal {
    background: var(--neu-card-bg) !important;
    border: none !important;
    box-shadow: var(--neu-out) !important;
}
/* The multi-item order summary, matched to the single-item price panel.
   Both list the same thing — parts, subtotal, tax, total — and they sit side by
   side on the board, so a ticket with three parts should not look like a
   different kind of object from one with a part.

   This rule used to say `.order-summary`, which matches NOTHING: that prefix
   only ever appears as .order-summary-row / -name / -price. The container is
   .order-items-summary, and while the selector was wrong the panel kept its
   base styling — white fill, hard 1px border, 10px radius — which is exactly
   the mismatch that showed up beside the raised, 16px price panel.

   Same three declarations .detail-chip gets, plus the radius, since this one
   does not inherit the panel radius from .detail-chip-full. */
body.neu-mode .order-items-summary {
    background: var(--neu-card-bg) !important;
    border: none !important;
    border-radius: var(--radius, 16px) !important;
    box-shadow: var(--neu-out-sm) !important;
}
/* The row rules were mixed for a white panel. On the card wash they read as
   table lines; softened to the value every other divider on this ticket uses. */
body.neu-mode .order-summary-row + .order-summary-row {
    border-top-color: rgba(63, 74, 86, 0.10) !important;
}
/* The call log keeps its own recess — it is a list of past events, not a
   summary panel, and it was only ever grouped here by accident. */
body.neu-mode .cl-item {
    background: var(--neu-sunk) !important;
    border: none !important;
    box-shadow: var(--neu-in-sm) !important;
}
body.neu-mode .cl-title,
body.neu-mode .cl-sub,
body.neu-mode .cl-item-meta,
body.neu-mode .cl-item-note { text-shadow: var(--neu-engrave); }

/* ── Completed section ── */
body.neu-mode .completed-card {
    background: var(--neu-card-bg) !important;
    border: none !important;
    box-shadow: var(--neu-out-sm) !important;
}
body.neu-mode .completed-name,
body.neu-mode .completed-total,
body.neu-mode .completed-count,
body.neu-mode .completed-section-title { text-shadow: var(--neu-engrave); }

/* ── Payment keys: the drawer's switch panel, in this theme ─────────────────
   checkout/index.css shapes these as raised rounded slabs, the same control as
   drawer/app.css's .reason-key. The catch-all near the top of this file —
   `body.neu-mode button:not(.emb-seg-btn):not(.accent-btn):not(.pcf-btn):not(.pos-unthemed)` at (0,3,2) — paints
   every button as a 999px pill and outranks it, which is what made these round.

   So the shape is restated here, at (0,4,2), where the theme can also give it a
   proper neu surface instead of the base sheet's flat gradient. The chosen
   state is NOT repeated: the .payment-icon-btn.active / .split-toggle-btn.active
   list above already presses it into the surface, and duplicating that here is
   how the two would eventually disagree. */
body.neu-mode .payment-icons-row > button:not(.emb-seg-btn):not(.accent-btn) {
    border-radius: 15px !important;
    background: var(--neu-bg) !important;
    background-image: none !important;
    box-shadow: var(--neu-out-sm) !important;
}
/* Hover: the same cool wash as the base sheet, tuned for this theme — a blue
   tint laid over the theme's own ground rather than a flat light fill, so the
   key still belongs to the surface it rises from. Declared after `background`
   on purpose: the shorthand would otherwise wipe the image out.

   :not(.active) because the .active list further up presses the chosen key into
   the surface, and this rule is more specific than that one — without the
   guard, hovering a chosen key would pop it back out and lose the only signal
   saying which payment was picked. */
body.neu-mode .payment-icons-row > button:not(.emb-seg-btn):not(.accent-btn):not(.active):hover {
    background: var(--neu-bg) !important;
    background-image: linear-gradient(160deg,
                      rgba(37, 99, 235, 0.13) 0%,
                      rgba(37, 99, 235, 0.05) 55%,
                      rgba(255, 255, 255, 0) 100%) !important;
    box-shadow: 7px 7px 14px var(--neu-dark), -7px -7px 14px var(--neu-light) !important;
}
/* The seam between keys, on the theme's ground: a groove rather than a line —
   one dark edge and one light one, which is how every other division in this
   theme is drawn. */
body.neu-mode .payment-icons-row > button + button::before {
    background: linear-gradient(180deg,
                rgba(195, 207, 226, 0) 0%,
                var(--neu-dark) 18%,
                var(--neu-dark) 82%,
                rgba(195, 207, 226, 0) 100%);
    box-shadow: 1px 0 0 var(--neu-light);
}
/* Pressed keys keep their travel. The .active list above swaps the surface but
   sets no transform, and without it the key changes colour without moving —
   which in a soft UI reads as broken rather than chosen. */
body.neu-mode .payment-icons-row > button.active {
    transform: translateY(2px);
}

/* ── Checkout text fields: a well with a lighter face ───────────────────────
   The rule near the top of this file puts every input in a well on --neu-bg —
   the SAME tone as the panel behind it. That is right for a search box sitting
   in a toolbar, but on the checkout's two required fields it left them reading
   as faint dents rather than as things you type into.

   The well stays, because inset IS the theme's word for "receives input" and
   swapping it for a raised field would say the opposite. What changes is the
   face: a hair lighter than the ground, with a white inner hairline catching
   the top edge. That is enough to separate the field from the panel without
   breaking the language.

   (0,3,1) against the base rule's (0,2,2), so it wins on specificity — both
   carry !important, which is why specificity is what decides. */
body.neu-mode .form-group .form-input {
    background: linear-gradient(180deg, #fbfcfe 0%, #f1f5fb 100%) !important;
    background-image: linear-gradient(180deg, #fbfcfe 0%, #f1f5fb 100%) !important;
    border: none !important;
    box-shadow: var(--neu-in-sm),
                inset 0 0 0 1px rgba(255, 255, 255, 0.85) !important;
}
body.neu-mode .form-group .form-input:focus {
    box-shadow: var(--neu-in),
                inset 0 0 0 1px rgba(255, 255, 255, 0.9),
                0 0 0 2px rgba(37, 99, 235, 0.28) !important;
}
body.neu-mode .form-group .form-input::placeholder {
    color: var(--neu-soft) !important;
}

/* ── Split payment fields ───────────────────────────────────────────────────
   Same problem and same answer as the customer fields above: the theme's input
   rule sits them in a well on --neu-bg, the tone of the panel around them, so
   three money boxes read as three faint dents. The well stays; the face gets a
   hair of lift.

   (0,3,2) against the base input rule's (0,2,2). Both carry !important, so
   specificity is what decides. */
body.neu-mode .split-panel .split-input-wrap input {
    background: linear-gradient(180deg, #fbfcfe 0%, #f1f5fb 100%) !important;
    background-image: linear-gradient(180deg, #fbfcfe 0%, #f1f5fb 100%) !important;
    border: none !important;
    border-radius: 12px !important;
    box-shadow: var(--neu-in-sm),
                inset 0 0 0 1px rgba(255, 255, 255, 0.85) !important;
}
body.neu-mode .split-panel .split-input-wrap input:focus {
    box-shadow: var(--neu-in),
                inset 0 0 0 1px rgba(255, 255, 255, 0.9),
                0 0 0 2px rgba(37, 99, 235, 0.28) !important;
}

/* ── Payment keys: label and chosen state ───────────────────────────────────
   The label takes --neu-raise — the token's own note says small figures only,
   which is exactly this: at 15px the two swapped offsets read as extrusion,
   where the big display numbers need filter: drop-shadow() instead because they
   are gradient-filled.

   The chosen key gets a real blue rather than the --neu-sunk fill the shared
   .active list gives every selectable control. That list is right for a status
   pill among several; here one key out of four records the payment, and a wash
   the colour of the panel made it argue with its neighbours rather than settle
   the question. The press is untouched — depth still comes from the inset, and
   the colour only confirms it.

   (0,4,2) against that list's (0,4,1), so this wins on element count. The
   :not() is what buys the fourth class. */
body.neu-mode .payment-icons-row > button:not(.emb-seg-btn) span {
    text-shadow: var(--neu-raise);
}
body.neu-mode .payment-icons-row > button:not(.emb-seg-btn).active {
    background: linear-gradient(160deg, #5a9bee 0%, #2f6fd0 55%, #2358b6 100%) !important;
    background-image: linear-gradient(160deg, #5a9bee 0%, #2f6fd0 55%, #2358b6 100%) !important;
    box-shadow: inset 0 2px 6px rgba(10, 40, 92, .40),
                inset 0 1px 0 rgba(255, 255, 255, .26),
                0 4px 14px rgba(37, 99, 235, .34) !important;
}
/* The shared list paints chosen labels --neu-ink with an engrave; on a blue
   face that is near-invisible and the engrave points the wrong way. */
body.neu-mode .payment-icons-row > button:not(.emb-seg-btn).active span {
    color: #ffffff !important;
    text-shadow: 0 1px 1px rgba(8, 35, 80, .55) !important;
}

/* ── Customer name and phone ────────────────────────────────────────────────
   The two fields a sale cannot be saved without, raised with this theme's own
   small-figure token. Restated here because the input rule near the top of the
   file sets `color: var(--neu-ink) !important`, and an !important declaration
   beats an id selector no matter how specific — so the base sheet's version
   would silently lose in this theme only. */
body.neu-mode #customerName,
body.neu-mode #customerPhone {
    color: var(--neu-ink) !important;
    text-shadow: var(--neu-raise) !important;
}
body.neu-mode #customerName::placeholder,
body.neu-mode #customerPhone::placeholder {
    color: var(--neu-soft) !important;
    text-shadow: none !important;
}

/* ── Search boxes ───────────────────────────────────────────────────────────
   The same lighter face the customer fields get, for the same reason: the input
   rule near the top of this file sits every field in a well on --neu-bg, the
   tone of the panel around it, so a search box reads as a dent. The well stays;
   the face lifts. */
body.neu-mode .customer-search-input {
    background: linear-gradient(180deg, #fbfcfe 0%, #f1f5fb 100%) !important;
    background-image: linear-gradient(180deg, #fbfcfe 0%, #f1f5fb 100%) !important;
    border: none !important;
    box-shadow: var(--neu-in-sm),
                inset 0 0 0 1px rgba(255, 255, 255, 0.85) !important;
}
body.neu-mode .customer-search-input:focus {
    box-shadow: var(--neu-in),
                inset 0 0 0 1px rgba(255, 255, 255, 0.9),
                0 0 0 2px rgba(37, 99, 235, 0.28) !important;
}

/* ── Accessory hover panel ──────────────────────────────────────────────────
   A raised card on the theme's ground, and the model rows lift on hover rather
   than taking the flat blue tint the base sheet gives them — in soft UI a row
   that only changes colour reads as broken.

   The panel is a <div>, so the button catch-all near the top of this file does
   not reach it and no specificity padding is needed here. The rows are <a>, for
   the same reason. */
body.neu-mode .acc-mega {
    background: var(--neu-card-bg);
    border: none;
    box-shadow: var(--neu-out);
}
body.neu-mode .acc-mega-head { text-shadow: var(--neu-engrave); }
body.neu-mode .acc-mega-list a:hover,
body.neu-mode .acc-mega-other:hover {
    background: var(--neu-bg);
    box-shadow: var(--neu-out-sm);
    color: var(--neu-ink);
}
body.neu-mode .acc-mega-other { border-top-color: var(--neu-dark); }

/* ── Accessory keys: the badges ─────────────────────────────────────────────
   The outer pill needs nothing here — the button catch-all near the top of this
   file already paints it as the theme's raised control, which is the shape the
   reference has.

   The badges do. They are <span>, so no catch-all reaches them, and the base
   sheet's white faces sit wrong on this theme's cooler ground. Raised on the
   pill, at the tight scale, so they read as sitting ON it rather than as holes
   cut into it. */
/* The badges are flat now, so there is nothing here to raise. The pill's own
   surface is left to the base sheet: its lighting was built to match this
   theme's ground and repeating it here would give two definitions to keep in
   step. Only the label and the chevron take the theme's ink. */
body.neu-mode .acc-label {
    color: var(--neu-soft);
    text-shadow: var(--neu-raise);
}
body.neu-mode .acc-item:hover .acc-label { color: var(--neu-mid); }
body.neu-mode .acc-go { color: var(--neu-soft); }

/* ── Search pill ────────────────────────────────────────────────────────────
   The wrapper is a <div>, so no button catch-all reaches it and the base
   sheet's white pill sits wrong on this theme's ground. Raised, matching the
   accessory keys beside it. The input inside keeps no surface of its own — the
   rule near the top of this file gives every field a well, and a well inside a
   raised pill reads as a box in a box. */
body.neu-mode .category-search-row .search-wrapper {
    background: var(--neu-bg);
    box-shadow: var(--neu-out-sm);
}
body.neu-mode .category-search-row .search-wrapper:focus-within {
    box-shadow: var(--neu-out-sm), 0 0 0 2px rgba(37, 99, 235, .28);
}
body.neu-mode .category-search-row .product-search,
body.neu-mode .category-search-row .product-search:focus {
    background: transparent !important;
    background-image: none !important;
    box-shadow: none !important;
    border: none !important;
    color: var(--neu-ink) !important;
}

/* The open state has to be restated here. The button catch-all near the top of
   this file sets background and box-shadow at (0,3,2) and outranks .acc-btn.on
   at (0,2,0), so without this the pill would light its chevron and turn it
   while staying visibly raised — saying open and closed at the same time.
   (0,4,1) via the wrapper class is enough to win. */
body.neu-mode .acc-item > .acc-btn.on {
    background: var(--neu-bg) !important;
    background-image: none !important;
    box-shadow: var(--neu-in-sm) !important;
}
body.neu-mode .acc-item > .acc-btn.on .acc-label { color: var(--neu-ink); }

/* The query text, raised like the labels either side of it. The base sheet's
   version is overridden here only because the input rule near the top of this
   file sets `color` with !important, which beats any specificity the base sheet
   could reach for. */
body.neu-mode .category-search-row .product-search {
    color: var(--neu-soft) !important;
    text-shadow: var(--neu-raise);
}
body.neu-mode .category-search-row .product-search::placeholder {
    color: var(--neu-faint) !important;
    text-shadow: none;
}
/* The seam between the two keys, as a groove on the theme's ground. */
body.neu-mode .acc-item + .acc-item::before {
    background: linear-gradient(180deg,
                rgba(195, 207, 226, 0) 0%,
                var(--neu-dark) 18%,
                var(--neu-dark) 82%,
                rgba(195, 207, 226, 0) 100%);
    box-shadow: 1px 0 0 var(--neu-light);
}

/* The four section labels, cut into the panel with this theme's own engrave
   token rather than the base sheet's hand-rolled pair — same offsets as every
   other engraved label in the theme, so they all catch light identically. */
body.neu-mode .form-group > label {
    text-shadow: var(--neu-engrave);
}

/* ── Product card: name raised, IMEI engraved ───────────────────────────────
   Same split as the base sheet, using this theme's own tokens so both catch
   light identically to every other raised and engraved label in it. */
body.neu-mode .gsm-title    { text-shadow: var(--neu-raise); }
body.neu-mode .gsm-imei-head { text-shadow: var(--neu-engrave); }

/* No text-shadow on the card figures. They are gradient-filled here, and a text
   shadow paints in the FOREGROUND — it would sit on top of the fill and halo
   the glyphs rather than shadow them. The raise comes from the drop-shadow
   filter list above, which filters the rendered output instead. */
body.neu-mode .gsm-hero b { text-shadow: none !important; }

/* ╔═══════════════════════════════════════════════════════════════════════════
   ║ TRIAL — part photos blended, no white tile. Pairs with the block of the
   ║ same name at the end of repairs/repairs.css.
   ║
   ║ TO REVERT: delete this block and that one. The raised-tile rule earlier in
   ║ this file is untouched and takes over again by itself.
   ║
   ║ Needed here because that earlier rule sets background and box-shadow with
   ║ !important, which no amount of specificity in the base sheet can beat.
   ╚═══════════════════════════════════════════════════════════════════════════ */
body.neu-mode .product-card.card-instock .part-photo,
body.neu-mode .product-card.card-restock .part-photo,
body.neu-mode .product-card.card-paid .part-photo,
body.neu-mode .product-card.card-deposit .part-photo,
body.neu-mode .product-card.card-pop .part-photo {
    background: transparent !important;
    padding: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    mix-blend-mode: multiply;
}
body.neu-mode .product-card.card-instock:hover .part-photo,
body.neu-mode .product-card.card-restock:hover .part-photo,
body.neu-mode .product-card.card-paid:hover .part-photo,
body.neu-mode .product-card.card-deposit:hover .part-photo,
body.neu-mode .product-card.card-pop:hover .part-photo {
    box-shadow: none !important;
}

/* ── Part cards in the checkout's anatomy ───────────────────────────────────
   The part name is ENGRAVED by the rule above, which was right when it sat on a
   flat card. In this layout it is the card's title, and its opposite number on
   the main checkout stands out — a name cut in on one page and raised on the
   other would make the two grids read as different components again. */
/* The part name is gradient-FILLED now, like the two figures beside it. A text
   shadow paints in the foreground and would sit on top of that fill, haloing the
   letters — so the raise has to come from the filter, which shadows the rendered
   output instead. Same reason the display figures use drop-shadow(). */
/* Engraved, matching the base sheet: highlight down-right, dark up-left. The
   offsets are --neu-engrave's, expressed as a filter because the name is
   gradient-filled and a text-shadow would paint over the fill. */
body.neu-mode .gsm-card .product-name {
    text-shadow: none;
    filter: drop-shadow(1px 1px 1px rgba(255, 255, 255, 0.90))
            drop-shadow(-1px -1px 1.5px rgba(63, 74, 86, 0.30));
}
/* The two figures are gradient-filled here, so no text-shadow: it would paint
   in the foreground, on top of the fill. The raise comes from the filter. */
body.neu-mode .gsm-card .gsm-hero b {
    text-shadow: none;
    filter: drop-shadow(-1px -1px 1px rgba(255, 255, 255, 0.95))
            drop-shadow(1px 1px 1.5px rgba(63, 74, 86, 0.34));
}
body.neu-mode .gsm-card .gsm-imei-head { text-shadow: var(--neu-engrave); }

/* The repairs price keeps its blue in this theme. `body.neu-mode .gsm-hero b`
   in the figure lists above paints every display figure with the grey
   --neu-figure-grad and !important, which is right for the checkout's price and
   battery but would strip the one colour the part card uses to separate the
   asking price from the reference values around it.

   b.product-price is (0,3,2) against that list's (0,2,2), and only the repairs
   card carries the class — the checkout's figures are unclassed <b>, so they
   keep the grey. */
body.neu-mode .gsm-card b.product-price {
    background: linear-gradient(175deg, #1d4d8f 0%, #2c6bb8 45%, #5b93d4 100%) !important;
    -webkit-background-clip: text !important;
    background-clip: text !important;
    -webkit-text-fill-color: transparent !important;
}

/* ============================================================================
   LAYAWAY — layaway/index.php and layaway/view_layaway.php
   ============================================================================
   These two pages were built outside the theme system: their own stylesheets
   paint cards with white fills, borders and drop shadows, and a blue table
   header. Linking neumorphic.css alone would have themed the topbar and the
   buttons through the catch-alls and left the page itself looking pasted on.

   Every rule here is (0,2,1) or better against the page sheets' (0,1,0), so
   source order between the files does not decide anything.

   The house rules this follows: no borders and no translucency, panels lift out
   of the page rather than sitting on it, inputs live in wells, buttons press IN
   on :active, and the money figures get the raised gradient treatment. */

/* ── Ground and panels ──────────────────────────────────────────────────── */
body.neu-mode .layaway-container,
body.neu-mode .view-container {
    background: transparent;
}

body.neu-mode .layaway-header,
body.neu-mode .layaway-table-container,
body.neu-mode .customer-card,
body.neu-mode .payment-section,
body.neu-mode .payment-form,
body.neu-mode .payment-history,
body.neu-mode .item-section {
    background: var(--neu-card-bg);
    border: none;
    border-radius: 24px;
    box-shadow: var(--neu-out);
}

/* A panel nested inside a panel is a WELL, not a second raised card — two
   stacked extrusions read as a mistake in soft UI.
   
   ONLY THE ONES THAT ARE ACTUALLY BOXES. .item-section, .item-detail and
   .lease-info are bare text blocks with no horizontal padding — they were
   separated by a border, not by a container. Sinking them into wells put every
   line flush against its own rounded corner, which is what made this card look
   like it was overflowing. A well needs padding to be a well; a run of text
   needs a divider. */
body.neu-mode .payment-form,
body.neu-mode .price-info {
    background: var(--neu-bg);
    border: none;
    border-radius: 18px;
    box-shadow: var(--neu-in-sm);
}

/* The dividers those blocks used to draw with a border. Two inset lines rather
   than one solid rule: a hairline dark over a hairline light is how an edge is
   cut into a surface in this theme, and it is the same pair used above Total
   Due. */
body.neu-mode .item-section {
    background: transparent;
    border-top: none;
    box-shadow: inset 0 1px 0 rgba(163, 177, 198, .45),
                inset 0 2px 0 rgba(255, 255, 255, .85);
}
body.neu-mode .item-detail,
body.neu-mode .lease-info {
    background: transparent;
    border: none;
    box-shadow: none;
}

body.neu-mode .layaway-header h1,
body.neu-mode .section-title,
body.neu-mode .payment-history-title,
body.neu-mode .customer-name {
    color: var(--neu-ink);
    text-shadow: var(--neu-raise);
}
body.neu-mode .layaway-header p,
body.neu-mode .customer-phone,
body.neu-mode .modal-form-label,
body.neu-mode .form-label,
body.neu-mode .no-data {
    color: var(--neu-mid);
    text-shadow: var(--neu-engrave);
}

/* ── The table ──────────────────────────────────────────────────────────────
   The blue header bar goes. It is the loudest thing on a page whose subject is
   the rows underneath it, and soft UI has no vocabulary for a solid fill that
   is not an accent. Rows use a VERTICAL-ONLY ramp: backgrounds sit on cells, so
   anything with a horizontal component restarts at every column. */
body.neu-mode .layaway-table thead,
body.neu-mode .payment-table thead {
    background: transparent;
}
body.neu-mode .layaway-table thead th,
body.neu-mode .payment-table thead th {
    background: transparent;
    color: var(--neu-mid);
    border: none;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-shadow: var(--neu-engrave);
}
body.neu-mode .layaway-table tbody tr,
body.neu-mode .payment-table tbody tr {
    background: var(--neu-row-bg);
}
body.neu-mode .layaway-table tbody tr:hover,
body.neu-mode .payment-table tbody tr:hover {
    background: var(--neu-bg);
}
body.neu-mode .layaway-table td,
body.neu-mode .layaway-table th,
body.neu-mode .payment-table td,
body.neu-mode .payment-table th {
    border-color: transparent;
    color: var(--neu-ink);
}

/* ── Status pills ───────────────────────────────────────────────────────────
   Kept coloured. Accents are deliberately NOT extruded in this theme — soft UI
   hides anything sharing the surface colour, and Active vs Completed is the one
   thing scanned down this column. */
body.neu-mode .status-badge {
    border: none;
    box-shadow: var(--neu-out-sm);
}

/* ── Money ──────────────────────────────────────────────────────────────────
   NOT given the raised-gradient treatment, deliberately. That is the house
   standard for LARGE amounts and these are 13px — at that size the same offsets
   read as a printing fault rather than as depth, which is why the rule in this
   file says big figures only. If the detail card ever grows a real headline
   figure, that selector goes in all three lists above; these do not.

   The divider above Total Due loses its border, like every border in this
   theme, and becomes a hairline well edge instead. */
body.neu-mode .price-row,
body.neu-mode .info-row {
    color: var(--neu-ink);
}
body.neu-mode .price-row span:first-child,
body.neu-mode .info-row span:first-child {
    color: var(--neu-mid);
}
body.neu-mode .price-row.total {
    border-top: none;
    box-shadow: inset 0 1px 0 rgba(163, 177, 198, .45),
                inset 0 2px 0 rgba(255, 255, 255, .85);
}

/* ── Inputs live in wells ───────────────────────────────────────────────── */
body.neu-mode .modal-form-input,
body.neu-mode .form-input,
body.neu-mode .form-select {
    background: var(--neu-bg) !important;
    background-image: none !important;
    border: none !important;
    border-radius: 14px !important;
    color: var(--neu-ink) !important;
    box-shadow: var(--neu-in-sm) !important;
}
body.neu-mode .modal-form-input:focus,
body.neu-mode .form-input:focus,
body.neu-mode .form-select:focus {
    box-shadow: var(--neu-in), 0 0 0 2px rgba(91, 141, 239, .22) !important;
}
body.neu-mode .modal-form-input::placeholder,
body.neu-mode .form-input::placeholder { color: var(--neu-soft) !important; }

/* ── The modal ──────────────────────────────────────────────────────────────
   Raised off the backdrop like every other panel, and no border. */
body.neu-mode .modal-content {
    background: var(--neu-card-bg);
    border: none;
    border-radius: 26px;
    box-shadow: 12px 12px 30px rgba(163, 177, 198, .55),
               -10px -10px 26px rgba(255, 255, 255, .95);
}
body.neu-mode .modal-header,
body.neu-mode .modal-footer {
    border-color: transparent;
    background: transparent;
}
body.neu-mode .modal-header h2 { color: var(--neu-ink); text-shadow: var(--neu-raise); }

/* ── The scan line under the IMEI box ───────────────────────────────────────
   Engraved rather than printed, like every other small label in this theme. */
body.neu-mode .lw-scan-wait,
body.neu-mode .lw-scan-ok,
body.neu-mode .lw-scan-bad { text-shadow: var(--neu-engrave); }

/* ── The one control that must be found fast ────────────────────────────────
   Add New Layaway, Add Payment and Save keep their fill and a coloured glow.
   Extruding them in the surface colour is exactly how soft UI loses its primary
   action. Declared !important so the button catch-all cannot flatten them —
   the same guard .search-circle-btn uses. */
body.neu-mode .btn-add-layaway,
body.neu-mode .btn-add-payment,
body.neu-mode .btn-edit-lease,
body.neu-mode .modal-btn-save {
    background: linear-gradient(135deg, #5b8def 0%, #3f6fd8 100%) !important;
    background-image: linear-gradient(135deg, #5b8def 0%, #3f6fd8 100%) !important;
    color: #fff !important;
    border: none !important;
    border-radius: 999px !important;
    box-shadow: 0 6px 16px rgba(63, 111, 216, .34),
                inset 0 1px 0 rgba(255, 255, 255, .30) !important;
    text-shadow: none !important;
}
body.neu-mode .btn-add-layaway:hover,
body.neu-mode .btn-add-payment:hover,
body.neu-mode .btn-edit-lease:hover,
body.neu-mode .modal-btn-save:hover {
    box-shadow: 0 8px 20px rgba(63, 111, 216, .42),
                inset 0 1px 0 rgba(255, 255, 255, .30) !important;
}
/* Pressed pushes IN, like every other control in this theme. */
body.neu-mode .btn-add-layaway:active,
body.neu-mode .btn-add-payment:active,
body.neu-mode .btn-edit-lease:active,
body.neu-mode .modal-btn-save:active {
    box-shadow: inset 3px 3px 7px rgba(30, 60, 130, .45),
                inset -2px -2px 6px rgba(255, 255, 255, .18) !important;
}

/* Delete stays red for the same reason Save stays blue: it is the one action
   here that cannot be undone from the page. */
body.neu-mode .btn-delete,
body.neu-mode .btn-delete-payment {
    background: linear-gradient(135deg, #ef6b7d 0%, #dc4a5f 100%) !important;
    color: #fff !important;
    border: none !important;
    box-shadow: 0 5px 14px rgba(220, 74, 95, .32) !important;
}

/* Everything else — View, Cancel, Call, Message, Print, Back — is extruded in
   the surface colour and picks that up from the button catch-all above. They
   only need their own fills and borders cleared. */
body.neu-mode .btn-view,
body.neu-mode .btn-call,
body.neu-mode .btn-message,
body.neu-mode .btn-print,
body.neu-mode .modal-btn-cancel,
body.neu-mode .back-btn {
    background: var(--neu-bg);
    background-image: none;
    border: none;
    color: var(--neu-mid);
    box-shadow: var(--neu-out-sm);
}
body.neu-mode .btn-view:hover,
body.neu-mode .btn-call:hover,
body.neu-mode .btn-message:hover,
body.neu-mode .btn-print:hover,
body.neu-mode .modal-btn-cancel:hover,
body.neu-mode .back-btn:hover {
    color: var(--neu-ink);
    box-shadow: 7px 7px 14px var(--neu-dark), -7px -7px 14px var(--neu-light);
}

/* The customer disc on the detail page. Extruded, not filled flat. */
body.neu-mode .customer-avatar {
    background: var(--neu-bg);
    color: var(--neu-mid);
    box-shadow: var(--neu-out), inset 0 1px 0 rgba(255, 255, 255, .8);
}

/* ── Search buttons wear the mark ───────────────────────────────────────────
   The in-page search discs (checkout and repairs) are in the accent list
   above and would otherwise come out blue→orange like Continue. They are
   search, so they take --neu-mark-grad like the topbar's — same disc, same
   mark, on every page. Later in the file than the accent block, at the same
   specificity, so this wins. */
body.neu-mode .search-circle-btn {
    background: var(--neu-mark-grad) !important;
    box-shadow: 0 4px 14px rgba(220, 38, 38, 0.28) !important;
}
body.neu-mode .search-circle-btn:hover {
    filter: brightness(1.08);
    box-shadow: 0 6px 18px rgba(220, 38, 38, 0.38) !important;
}

/* ── User panel (topbar) ─────────────────────────────────────────────────────
   Raised card already (the .user-dropdown rule above). Inside it: the facts
   block sinks into the card, the chips and tiles rise from it, and the photo
   disc becomes a socket. */
body.neu-mode .up-photo { background: var(--neu-bg); box-shadow: var(--neu-in-sm); }
body.neu-mode .topbar-avatar.topbar-avatar-xl { box-shadow: var(--neu-out-sm); }
body.neu-mode .up-edit { background: var(--neu-bg); border: none; box-shadow: var(--neu-out-sm); color: var(--neu-mid); }
body.neu-mode .up-edit:hover { color: var(--neu-ink); }
body.neu-mode .up-facts { background: var(--neu-bg); box-shadow: var(--neu-in-sm); }
body.neu-mode .up-chip, body.neu-mode .up-tile { background: var(--neu-card-bg); border: none; box-shadow: var(--neu-out-sm); }
body.neu-mode .up-tile:hover { box-shadow: 7px 7px 14px var(--neu-dark), -7px -7px 14px var(--neu-light); }
body.neu-mode .up-arrow { background: var(--neu-bg); border: none; box-shadow: var(--neu-in-sm); }
body.neu-mode .up-name { color: var(--neu-ink); text-shadow: var(--neu-engrave); }
body.neu-mode .up-id { background: var(--neu-bg); box-shadow: var(--neu-in-sm); }

/* ── Trial (2026-09-09): a flat topbar ──────────────────────────────────────
   No cast shadow and no rounded bottom; one divider line carries the edge.
   Delete this block to put the raised bar back. */
body.neu-mode .topbar {
    box-shadow: none !important;
    border-radius: 0 !important;
    border-bottom: none !important;
}

/* ── Trial (2026-09-09): the centre notch ───────────────────────────────────
   The three quick links sit in a white tab that hangs from the top edge of
   the bar and drops a little below it: flat, rounded at the bottom, flared
   where its sides meet the top edge. The flares are the two pseudo-elements —
   a square each, filled with the tab colour except for a quarter-circle cut
   from the corner nearest the tab. The bottom padding keeps the links level
   with the rest of the bar. Delete this block to remove the notch. */
body.neu-mode.notch-on .topbar-notch {
    position: relative;
    align-self: flex-start;
    height: 92px;
    padding: 0 26px 8px;
    margin: 0 30px;
    background: #dee3e8;
    background: linear-gradient(to bottom, #adbfce 0%, #dee3e8 50%, #f4faff 100%);
    border-radius: 0 0 28px 28px;
    /* A cast shadow that follows the whole silhouette, flares included —
       drop-shadow() traces the alpha of the element and its pseudo-elements,
       where box-shadow would trace only the rectangle. */
    filter: drop-shadow(0 4px 8px rgba(13, 42, 82, 0.06));
}
body.neu-mode.notch-on .topbar-notch::before,
body.neu-mode.notch-on .topbar-notch::after {
    content: '';
    position: absolute;
    top: 0;
    width: 30px;
    height: 30px;
    pointer-events: none;
    background: linear-gradient(to bottom, #adbfce 0%, #dee3e8 50%, #f4faff 100%);
    background-size: 100% 80px;
    background-repeat: no-repeat;
}
body.neu-mode.notch-on .topbar-notch::before {
    left: -30px;
    -webkit-mask: radial-gradient(circle at 0 100%, transparent 29.5px, #000 30px);
    mask: radial-gradient(circle at 0 100%, transparent 29.5px, #000 30px);
}
body.neu-mode.notch-on .topbar-notch::after {
    right: -30px;
    -webkit-mask: radial-gradient(circle at 100% 100%, transparent 29.5px, #000 30px);
    mask: radial-gradient(circle at 100% 100%, transparent 29.5px, #000 30px);
}
/* With the tab hanging past the bar and the divider below that, the cards need
   more room at the top than the base sheet's 90px gives them. */
body.neu-mode.notch-on .main-content { padding-top: 136px; }
/* The three links as glass pills on the light tab: white to pale blue like
   the tab itself, a faint blue rim, a white highlight along the top edge and
   a soft shadow onto the tab. Icons keep their blue drop shadow. Hover lifts
   and brightens, press sinks. */
body.neu-mode .topbar-notch .topbar-center { gap: 14px; }
body.neu-mode .topbar-notch .topbar-action {
    height: 46px; margin: 0; padding: 0 20px; gap: 10px;
    color: var(--neu-ink);
    background: linear-gradient(180deg, rgba(255,255,255,0.62) 0%, rgba(255,255,255,0.38) 100%);
    border: 1px solid rgba(255,255,255,0.75);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
    box-shadow: inset 0 1px 0 #ffffff, inset 0 -2px 6px rgba(26, 95, 168, 0.06),
                0 6px 14px rgba(13, 42, 82, 0.10), 0 1px 2px rgba(13, 42, 82, 0.08);
    transition: box-shadow .2s ease, transform .15s ease, color .2s ease;
}
body.neu-mode .topbar-notch .topbar-action-label { color: var(--neu-ink); font-size: 11px; text-shadow: var(--neu-engrave); }
body.neu-mode .topbar-notch .topbar-action:hover {
    background: linear-gradient(180deg, rgba(255,255,255,0.78) 0%, rgba(255,255,255,0.52) 100%);
    box-shadow: inset 0 1px 0 #ffffff, inset 0 -2px 6px rgba(26, 95, 168, 0.05),
                0 10px 20px rgba(13, 42, 82, 0.14), 0 1px 2px rgba(13, 42, 82, 0.08);
    color: var(--neu-ink); transform: translateY(-1px);
}
body.neu-mode .topbar-notch .topbar-action:hover .topbar-action-label { color: var(--neu-blue); }
body.neu-mode .topbar-notch .topbar-action:active {
    transform: translateY(0);
    box-shadow: inset 0 2px 6px rgba(26, 95, 168, 0.16), inset 0 1px 0 rgba(26, 95, 168, 0.06);
}
/* ── Trial (2026-09-10): the liquid-glass rail ──────────────────────────────
   Inside the notch the three links sit in one white pill, icon over label,
   and a glass lens slides between them: a translucent blob with a bright
   rim, a soft inner shade on its far side, a light cast shadow, and a faint
   rainbow fringe at its edge where the light bends. The lens rests on the
   link for the page we are on (topbar.php sets .is-here and moves it).
   Delete this block to go back to the frosted pills. */
body.neu-mode .topbar-notch .topbar-center {
    gap: 0;
    padding: 6px;
    border-radius: 999px;
    background: #ffffff;
    box-shadow: 0 10px 26px rgba(13, 42, 82, 0.12), 0 1px 2px rgba(13, 42, 82, 0.06), inset 0 1px 0 #ffffff;
}
body.neu-mode .topbar-notch .topbar-action,
body.neu-mode .topbar-notch .topbar-action:hover,
body.neu-mode .topbar-notch .topbar-action:active {
    flex-direction: column; justify-content: center; gap: 5px;
    width: 118px; height: 64px; margin: 0; padding: 0;
    border: 0; border-radius: 999px;
    background: transparent; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none;
    transform: none; color: var(--neu-ink);
    transition: transform .3s cubic-bezier(.22,.8,.28,1);
}
body.neu-mode .topbar-notch .topbar-action:hover { transform: scale(1.06); }
body.neu-mode .topbar-notch .topbar-action img { width: 26px; height: 26px; filter: drop-shadow(0 2px 3px rgba(13, 42, 82, 0.18)) !important; }
body.neu-mode .topbar-notch .topbar-action-label,
body.neu-mode .topbar-notch .topbar-action:hover .topbar-action-label { color: #3b4657; font-size: 10.5px; letter-spacing: .18em; text-shadow: none; }
body.neu-mode .topbar-notch .topbar-action.is-here .topbar-action-label { color: #d61c26; }
body.neu-mode .topbar-lens {
    display: block;
    position: absolute; top: 6px; left: 6px; width: 118px; height: 64px;
    border-radius: 999px; pointer-events: none; z-index: 2; opacity: 0;
    box-shadow: inset 0 0 0 1px rgba(255,255,255,0.9), inset 4px 4px 10px rgba(255,255,255,0.95),
                inset -4px -5px 12px rgba(13, 42, 82, 0.12),
                0 12px 24px rgba(13, 42, 82, 0.16), 0 2px 5px rgba(13, 42, 82, 0.10);
    transition: left .38s cubic-bezier(.22,.8,.28,1), width .38s cubic-bezier(.22,.8,.28,1), opacity .25s ease;
}
body.neu-mode .topbar-lens.on { opacity: 1; }
/* The fringe: a rainbow ring, blurred and mostly transparent, only at the rim. */
body.neu-mode .topbar-lens::before {
    content: ''; position: absolute; inset: -1px; border-radius: inherit; padding: 2.5px;
    background: conic-gradient(from 210deg,
        rgba(255, 70, 170, 0) 0%, rgba(255, 70, 170, 0.55) 6%, rgba(90, 200, 255, 0.55) 13%, rgba(255, 225, 90, 0.50) 20%, rgba(255, 70, 170, 0) 28%,
        rgba(255, 70, 170, 0) 58%, rgba(90, 200, 255, 0.50) 66%, rgba(255, 70, 170, 0.50) 74%, rgba(255, 225, 90, 0.45) 82%, rgba(255, 70, 170, 0) 92%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor; mask-composite: exclude;
    filter: blur(1.3px); opacity: 0.9;
}
/* Without the notch the rail sits inside the 64px bar, so it runs shorter:
   46px links in a 56px pill. With the notch on, the taller sizes above apply. */
body.neu-mode:not(.notch-on) .topbar-notch .topbar-center { padding: 5px; }
body.neu-mode:not(.notch-on) .topbar-notch .topbar-action { height: 46px; width: 112px; gap: 3px; }
body.neu-mode:not(.notch-on) .topbar-notch .topbar-action img { width: 22px; height: 22px; }
body.neu-mode:not(.notch-on) .topbar-lens { top: 5px; left: 5px; height: 46px; width: 112px; }
/* ── Trial (2026-09-10): one white panel for the whole bar ──────────────────
   With the notch off, the bar itself becomes the panel: a floating white
   pill inset from the rail and the edges, carrying the brand, the links, the
   bells, the badge and the search. The rail behind the links gives up its
   own white and keeps only the lens. */
body.neu-mode:not(.notch-on) .topbar {
    top: 8px; left: 80px; right: 16px; height: 60px;
    padding: 0 30px 0 34px;
    background: #ffffff !important;
    border-radius: 999px !important;
    /* Tight on purpose: the content starts 22px under the bar, and a wide
       shadow was washing over the first row of cards. */
    box-shadow: 0 3px 10px rgba(13, 42, 82, 0.08), 0 1px 2px rgba(13, 42, 82, 0.05), inset 0 1px 0 #ffffff !important;
}
body.neu-mode:not(.notch-on) .topbar-notch .topbar-center { padding: 0; background: transparent; box-shadow: none; }
body.neu-mode:not(.notch-on) .topbar-lens { top: 0; left: 0; }
/* The lens: clear through the middle, frosted only toward the rim. Both the
   blur and the white tint live on a ring — an ellipse mask leaves the centre
   untouched — so what sits under the lens stays readable. */
body.neu-mode .topbar-lens::after {
    content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
    background: radial-gradient(ellipse at center, rgba(255,255,255,0) 48%, rgba(255,255,255,0.45) 74%, rgba(255,255,255,0.72) 100%);
    backdrop-filter: blur(3px) saturate(1.4); -webkit-backdrop-filter: blur(3px) saturate(1.4);
    -webkit-mask: radial-gradient(ellipse at center, transparent 52%, #000 74%);
    mask: radial-gradient(ellipse at center, transparent 52%, #000 74%);
}
/* More air between the links, and a lens that overhangs the link it sits on. */
body.neu-mode:not(.notch-on) .topbar-notch .topbar-center { gap: 18px; }
body.neu-mode:not(.notch-on) .topbar-lens { top: -7px; height: 60px; box-sizing: content-box; padding: 0 10px; margin-left: -10px; }
/* ── Trial (2026-09-10): glass bells and badge ──────────────────────────────
   The three bells and the user badge as frosted glass: a translucent white
   fill, a bright rim, a highlight along the top edge, a soft cast shadow and
   a real backdrop blur. Glass needs something behind it to bend, so two soft
   colour blooms in the brand's blue and red sit under the group, blurred,
   and show through the buttons and the gaps between them. */
body.neu-mode:not(.notch-on) .topbar-end .topbar-right { position: relative; padding: 0 6px; }
body.neu-mode:not(.notch-on) .topbar-end .topbar-right::before {
    content: ''; position: absolute; inset: -6px -44px; z-index: 0; pointer-events: none;
    background:
        radial-gradient(circle at 18% 50%, rgba(26, 95, 168, 0.34) 0%, rgba(26, 95, 168, 0) 55%),
        radial-gradient(circle at 56% 50%, rgba(120, 170, 235, 0.26) 0%, rgba(120, 170, 235, 0) 50%),
        radial-gradient(circle at 88% 50%, rgba(214, 28, 38, 0.24) 0%, rgba(214, 28, 38, 0) 55%);
    filter: blur(12px);
    /* The blur spills past the box, and the box ends at the bar's edges; the
       mask clips the paint to the box again and fades it before the edge. */
    /* Two fades, intersected: top-to-bottom keeps it inside the bar, and
       left-to-right lets both ends dissolve instead of stopping at the box. */
    -webkit-mask: linear-gradient(to bottom, transparent 0%, #000 32%, #000 68%, transparent 100%),
                  linear-gradient(to right, transparent 0%, #000 22%, #000 78%, transparent 100%);
    -webkit-mask-composite: source-in;
    mask: linear-gradient(to bottom, transparent 0%, #000 32%, #000 68%, transparent 100%),
          linear-gradient(to right, transparent 0%, #000 22%, #000 78%, transparent 100%);
    mask-composite: intersect;
}
body.neu-mode:not(.notch-on) .topbar-end .topbar-right > * { position: relative; z-index: 1; }
body.neu-mode:not(.notch-on) .topbar-end .topbar-icon-btn,
body.neu-mode:not(.notch-on) .topbar-end .topbar-user-btn {
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.78) 0%, rgba(255, 255, 255, 0.42) 55%, rgba(255, 255, 255, 0.62) 100%) !important;
    border: 1px solid rgba(255, 255, 255, 0.95) !important;
    box-shadow: 0 8px 20px rgba(13, 42, 82, 0.12), 0 1px 2px rgba(13, 42, 82, 0.06),
                inset 0 1px 0 rgba(255, 255, 255, 1), inset 0 -1px 0 rgba(13, 42, 82, 0.06),
                inset 0 0 0 1px rgba(26, 95, 168, 0.06) !important;
    backdrop-filter: blur(12px) saturate(1.6); -webkit-backdrop-filter: blur(12px) saturate(1.6);
    transition: transform .18s ease, box-shadow .18s ease;
}
body.neu-mode:not(.notch-on) .topbar-end .topbar-user-btn { border-radius: 999px !important; padding: 5px 14px 5px 5px; }
body.neu-mode:not(.notch-on) .topbar-end .topbar-icon-btn:hover,
body.neu-mode:not(.notch-on) .topbar-end .topbar-user-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 12px 26px rgba(13, 42, 82, 0.16), 0 1px 2px rgba(13, 42, 82, 0.06),
                inset 0 1px 0 rgba(255, 255, 255, 1), inset 0 -1px 0 rgba(13, 42, 82, 0.06),
                inset 0 0 0 1px rgba(26, 95, 168, 0.10) !important;
}
body.neu-mode:not(.notch-on) .topbar-end .topbar-notif-wrap:has(.open) > .topbar-icon-btn,
body.neu-mode:not(.notch-on) .topbar-end .topbar-user-wrap:has(.open) > .topbar-user-btn {
    transform: none;
    box-shadow: inset 0 2px 6px rgba(13, 42, 82, 0.16), inset 0 0 0 1px rgba(26, 95, 168, 0.10) !important;
}
body.neu-mode:not(.notch-on) .topbar-end .topbar-sep { background: rgba(26, 95, 168, 0.16); }
/* A larger badge: 44px avatar, bigger name and role, more room around them. */
body.neu-mode:not(.notch-on) .topbar-end .topbar-user-btn { padding: 5px 18px 5px 6px; gap: 11px; }
body.neu-mode:not(.notch-on) .topbar-end .topbar-user-btn .topbar-avatar { width: 44px; height: 44px; font-size: 15px; }
body.neu-mode:not(.notch-on) .topbar-end .topbar-user-btn .topbar-user-name { font-size: 15px; }
body.neu-mode:not(.notch-on) .topbar-end .topbar-user-btn .topbar-user-role { font-size: 11.5px; }
/* Clear glass rather than frosted: no blur, only a faint tint, a bright rim,
   and a reflection — a soft diagonal streak plus a sheen along the top edge,
   painted on a pseudo-element so it sits over the fill and under nothing. */
body.neu-mode:not(.notch-on) .topbar-end .topbar-icon-btn,
body.neu-mode:not(.notch-on) .topbar-end .topbar-user-btn {
    position: relative; overflow: hidden;
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.34) 0%, rgba(255, 255, 255, 0.10) 50%, rgba(255, 255, 255, 0.26) 100%) !important;
    border: 1px solid rgba(255, 255, 255, 0.92) !important;
    backdrop-filter: none; -webkit-backdrop-filter: none;
    box-shadow: 0 8px 20px rgba(13, 42, 82, 0.12), 0 1px 2px rgba(13, 42, 82, 0.06),
                inset 0 1px 0 rgba(255, 255, 255, 0.95), inset 0 -1px 0 rgba(13, 42, 82, 0.08),
                inset 0 0 0 1px rgba(26, 95, 168, 0.06) !important;
}
body.neu-mode:not(.notch-on) .topbar-end .topbar-icon-btn::after,
body.neu-mode:not(.notch-on) .topbar-end .topbar-user-btn::after {
    content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 2;
    background:
        linear-gradient(115deg, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0.28) 41%, rgba(255, 255, 255, 0.28) 45%, rgba(255, 255, 255, 0) 56%),
        radial-gradient(ellipse 80% 40% at 50% 0%, rgba(255, 255, 255, 0.45) 0%, rgba(255, 255, 255, 0) 100%);
}
/* The bells' count badges must stay above the reflection. */
body.neu-mode:not(.notch-on) .topbar-end .topbar-icon-btn .topbar-badge { z-index: 3; }

/* ── Active repairs: segments, parked strip, choice dialog ──────────────── */
body.neu-mode .ar-seg { background: var(--neu-bg); border: none; box-shadow: var(--neu-out-sm); color: var(--neu-mid); }
body.neu-mode .ar-seg.on { background: var(--neu-bg); color: var(--neu-blue); box-shadow: var(--neu-in-sm); }
body.neu-mode .ar-seg.on b { background: var(--neu-blue); color: #fff; }
body.neu-mode .park-strip { background: rgba(217, 119, 6, 0.09); border-bottom: 1px solid rgba(217, 119, 6, 0.22); }
body.neu-mode .park-strip-closed { background: rgba(100, 116, 139, 0.10); border-bottom-color: rgba(100, 116, 139, 0.22); }
body.neu-mode .park-btn { box-shadow: var(--neu-out-sm); }
body.neu-mode .park-btn:active { box-shadow: var(--neu-in-sm); }
body.neu-mode .ar-choice { background: var(--neu-card-bg); box-shadow: var(--neu-out); }
body.neu-mode .ar-choice-item { background: var(--neu-bg); border: none; box-shadow: var(--neu-out-sm); }
body.neu-mode .ar-choice-item:has(input:checked) { box-shadow: var(--neu-in-sm); }
body.neu-mode .ar-choice-note { background: var(--neu-bg); border: none; box-shadow: var(--neu-in-sm); }
/* The park button on the repair cards: engraved like edit and delete beside it, amber under the pointer. */
body.neu-mode .icon-btn-park:hover { background: transparent !important; border: none !important; box-shadow: none !important; color: #b45309 !important; }
/* Repair History tabs. */
body.neu-mode .cr-tabs button { background: var(--neu-bg); border: none; box-shadow: var(--neu-out-sm); color: var(--neu-mid); }
body.neu-mode .cr-tabs button.on { color: var(--neu-blue); box-shadow: var(--neu-in-sm); }
body.neu-mode .cr-tabs button.on b { background: var(--neu-blue); color: #fff; }
/* Cards view on the active repairs board: the customer name raised the way the
   ticket card's is — the headline face, no groove, the popup drop-shadow. */
body.neu-mode .ar-hcard.gsm-card .gsm-title {
    font-family: var(--neu-figure) !important;
    font-weight: 700 !important;
    letter-spacing: 0.005em !important;
    text-shadow: none;
    filter:
        drop-shadow(-1px -1px 1px rgba(255, 255, 255, 0.95))
        drop-shadow(2px 2px 3px rgba(146, 162, 188, 0.55));
}
/* The eye on the Cards view: engraved like edit, park and delete; blue under the pointer. */
body.neu-mode .icon-btn-eye:hover { background: transparent !important; border: none !important; box-shadow: none !important; color: var(--primary, #2563EB) !important; }
body.neu-mode .ar-hcard.gsm-card .ar-h-pop { background: var(--neu-card-bg); border: none; box-shadow: var(--neu-out); }
/* The Cards view panel stays glass in this theme too; the theme's raised card fill would make it opaque. */
body.neu-mode .ar-hcard.gsm-card .ar-h-pop {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.70) 0%, rgba(240, 245, 252, 0.52) 100%);
  border: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 16px 40px rgba(13, 42, 82, 0.20), inset 0 1px 0 rgba(255, 255, 255, 0.95);
}
/* Ticket card name row: the contact and print buttons stay bare glyphs here too —
   the button catch-all above would raise each one on its own plate. */
body.neu-mode .ar-hcard .ar-h-contact .contact-btn-sm, body.neu-mode .ar-hcard .ar-h-contact .contact-btn-sm:hover,
body.neu-mode .ar-hcard .ar-h-contact .contact-btn-sm:active { background: transparent !important; box-shadow: none !important; border: none !important; transform: none; }
/* The more button on the ticket stub: engraved with the rest. */
body.neu-mode .icon-btn-more { background: transparent !important; border: none !important; box-shadow: none !important; }
body.neu-mode .ar-hcard .ar-h-act { background: var(--neu-card-bg); border: none; box-shadow: var(--neu-out-sm); }
body.neu-mode .ar-hcard .ar-h-act:hover { box-shadow: var(--neu-in-sm); }
/* The delete badge on the ticket cards: its ring in the page colour so it
   reads as sitting on the surface, and the theme's soft drop beneath it. */
body.neu-mode .ar-hcard.gsm-card .ar-h-x { border-color: var(--neu-bg, #e4ebf5); box-shadow: 4px 4px 10px rgba(163, 177, 198, 0.55), -2px -2px 6px rgba(255, 255, 255, 0.85); }
body.neu-mode .ar-hcard.gsm-card .ar-h-x:hover { box-shadow: 5px 5px 12px rgba(163, 177, 198, 0.65), -2px -2px 6px rgba(255, 255, 255, 0.85); }

/* ── Dashboard sales table: flat rows, the row is the button ──────────────
   (2026-09-14) The same workflow the Liquid theme has: the View column is
   hidden — the row itself opens the receipt (index.php wires the click) — and
   the rows go flat: no extrusion, no pill corners, a hairline between them.
   Scoped to the dashboard's .table-wrap so every other table keeps its
   raised rows. The View button stays in the DOM, unseen: its data-sale is how
   the row knows which receipt is its own. */
body.neu-mode .table-wrap table th:last-child,
body.neu-mode .table-wrap table td:last-child:not([colspan]) { display: none; }
body.neu-mode .table-wrap table { border-spacing: 0 !important; }
body.neu-mode .table-wrap tbody td {
    background: transparent !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    border-bottom: 1px solid rgba(63, 74, 86, 0.12) !important;
}
body.neu-mode .table-wrap tbody tr:last-child td { border-bottom: none !important; }
body.neu-mode #salesTableBody tr:has(.row-receipt-btn) { cursor: pointer; }
body.neu-mode #salesTableBody tr:has(.row-receipt-btn):hover td { background: rgba(255, 255, 255, 0.55) !important; }
