/* 10-desktop-ios18.css
 *
 * iOS 18 visual layer for the desktop dashboard. Purely additive — every
 * selector is gated on `body.ios18-desktop`, which is set by the inline
 * toggle in dashboard.html ONLY when not `mobile-touch-ui`.
 *
 * Cascade-last (loaded after 09-mobile-codex.css) so it wins by source
 * order at equal specificity. No edits to 01/07/08; no !important.
 *
 * Toggle on:  localStorage.setItem('ios18-desktop','1'); location.reload()
 * Toggle off: localStorage.removeItem('ios18-desktop'); location.reload()
 * One-shot:   append ?ios18=1 to the URL.
 */

/* ============================================================
 * 1. Token aliases (light)
 * ============================================================
 * Defined on body.ios18-desktop so they inherit everywhere we
 * use them below. Read-only — never overwrite global tokens.
 */
body.ios18-desktop {
    --r-card-ios18:    18px;
    --r-card-ios18-sm: 14px;
    --r-pill-ios18:    var(--r-full);

    /* Translucent surfaces — color-mix lets dark mode reuse the same
     * declarations because var(--surface) flips with [data-theme]. */
    --surface-glass:        color-mix(in oklab, var(--surface) 78%, transparent);
    --surface-glass-strong: color-mix(in oklab, var(--surface) 88%, transparent);
    --border-glass:         color-mix(in oklab, var(--border) 70%, transparent);

    /* Softer iOS-flavored shadows. Less ink, more diffusion. */
    --shadow-soft:    0 1px 2px rgba(15, 27, 45, 0.04),
                      0 8px 24px rgba(15, 27, 45, 0.06);
    --shadow-soft-lg: 0 2px 6px rgba(15, 27, 45, 0.05),
                      0 18px 40px rgba(15, 27, 45, 0.10);
    --shadow-pop:     0 6px 18px rgba(15, 27, 45, 0.10),
                      0 24px 60px rgba(15, 27, 45, 0.14);

    --accent-ios18: var(--accent);
}

/* Token aliases (dark) — heavier diffusion + true-black base shadows. */
body.ios18-desktop[data-theme="dark"],
[data-theme="dark"] body.ios18-desktop {
    --surface-glass:        color-mix(in oklab, var(--surface) 70%, transparent);
    --surface-glass-strong: color-mix(in oklab, var(--surface) 84%, transparent);
    --border-glass:         color-mix(in oklab, var(--border) 75%, transparent);

    --shadow-soft:    0 1px 2px rgba(0, 0, 0, 0.35),
                      0 8px 24px rgba(0, 0, 0, 0.40);
    --shadow-soft-lg: 0 2px 6px rgba(0, 0, 0, 0.40),
                      0 18px 40px rgba(0, 0, 0, 0.55);
    --shadow-pop:     0 6px 18px rgba(0, 0, 0, 0.50),
                      0 24px 60px rgba(0, 0, 0, 0.65);
}


/* ============================================================
 * 2. Sidebar + top strip — glass material
 * ============================================================ */
body.ios18-desktop .app-sidebar {
    background: var(--surface-glass);
    backdrop-filter: blur(24px) saturate(140%);
    -webkit-backdrop-filter: blur(24px) saturate(140%);
    border-right-color: var(--border-glass);
}

body.ios18-desktop .site-header {
    background: var(--surface-glass);
    backdrop-filter: blur(24px) saturate(140%);
    -webkit-backdrop-filter: blur(24px) saturate(140%);
    border-bottom-color: var(--border-glass);
}

/* Sidebar rows — softer corners, tap-style press */
body.ios18-desktop .sidebar-row,
body.ios18-desktop .sidebar-row-secondary {
    border-radius: 12px;
    transition: background-color 200ms ease, transform 200ms ease;
}
body.ios18-desktop .sidebar-row:active,
body.ios18-desktop .sidebar-row-secondary:active {
    transform: scale(0.985);
}

/* Repeat the .is-active chain so we don't lose the active background. */
body.ios18-desktop .sidebar-row.is-active {
    border-radius: 12px;
}

body.ios18-desktop .sidebar-user-chip {
    border-radius: 14px;
    transition: background-color 200ms ease, box-shadow 200ms ease;
}
body.ios18-desktop .sidebar-user-chip:hover {
    box-shadow: var(--shadow-soft);
}

/* Header icon buttons — pill press */
body.ios18-desktop .site-header .header-icon-btn {
    transition: background-color 200ms ease, transform 200ms ease, box-shadow 200ms ease;
}
body.ios18-desktop .site-header .header-icon-btn:hover {
    box-shadow: var(--shadow-soft);
}
body.ios18-desktop .site-header .header-icon-btn:active {
    transform: scale(0.94);
}


/* ============================================================
 * 3. Job card — rounded iOS card + cleaner hover
 * ============================================================ */
body.ios18-desktop .job-card {
    border-radius: var(--r-card-ios18);
    border-color: var(--border-glass);
    box-shadow: none;
    transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
}
body.ios18-desktop .job-card:hover {
    box-shadow: var(--shadow-soft);
}

/* Repeat the .is-expanded chain so the larger card gets the iOS treatment
 * rather than falling back to the base .job-card hover defined above. */
body.ios18-desktop .job-card.is-expanded {
    border-radius: var(--r-card-ios18);
    box-shadow: var(--shadow-soft-lg);
}
body.ios18-desktop .job-card.is-expanded:hover {
    box-shadow: var(--shadow-soft-lg);
}

/* Header hover — match the existing subtle tint, just round it */
body.ios18-desktop .job-card .job-header {
    border-radius: var(--r-card-ios18);
    transition: background-color 200ms ease;
}

/* Thumbnail — keep aspect, round to match new card radius */
body.ios18-desktop .jc-thumb {
    border-radius: var(--r-card-ios18-sm);
}
body.ios18-desktop .jc-thumb-photo {
    border-radius: var(--r-card-ios18-sm);
}


/* ============================================================
 * 4. Section card — nested softer panels
 * ============================================================
 * IMPORTANT: do NOT redeclare --sc-tint-bg / --sc-tint-fg. Per-section
 * tints are set by [data-section="…"] in 07-desktop.css and we want
 * them to keep working. We only touch radius/border/shadow here.
 */
body.ios18-desktop .section-card {
    border-radius: var(--r-card-ios18-sm);
    border-color: var(--border-glass);
    box-shadow: none;
    transition: box-shadow 200ms ease, border-color 200ms ease;
}
body.ios18-desktop .section-card:hover {
    box-shadow: var(--shadow-soft);
}

/* Repeat .open chain — the existing rule sets a heavier shadow we want
 * to soften, and we must not lose its layout-affecting properties. */
body.ios18-desktop .section-card.open {
    border-radius: var(--r-card-ios18-sm);
    box-shadow: var(--shadow-soft);
}

body.ios18-desktop .section-card-header {
    border-radius: var(--r-card-ios18-sm);
    transition: background-color 200ms ease;
}

/* Re-state the .open .section-card-header chain at the same specificity. */
body.ios18-desktop .section-card.open .section-card-header {
    border-radius: var(--r-card-ios18-sm) var(--r-card-ios18-sm) 0 0;
}

/* Job-card-scoped section card — repeat the chain that 08-cards-v2.css
 * uses, otherwise its more-specific .job-card.is-expanded .section-card
 * rules win and we'd see no radius change inside expanded cards. */
body.ios18-desktop .job-card.is-expanded .section-card {
    border-radius: var(--r-card-ios18-sm);
    border-color: var(--border-glass);
    box-shadow: none;
}
body.ios18-desktop .job-card.is-expanded .section-card.open {
    border-radius: var(--r-card-ios18-sm);
    box-shadow: var(--shadow-soft);
}


/* ============================================================
 * 5. Stat tiles + filter bar — soft panels
 * ============================================================ */
body.ios18-desktop .stats-bar .stat-card,
body.ios18-desktop .stat-card {
    border-radius: var(--r-card-ios18-sm);
    border-color: var(--border-glass);
    box-shadow: none;
    transition: box-shadow 200ms ease, transform 200ms ease, border-color 200ms ease;
}
body.ios18-desktop .stat-card:hover {
    box-shadow: var(--shadow-soft);
    transform: translateY(-1px);
}

/* .stat-card.sort-active — keep the active treatment, soften the chrome. */
body.ios18-desktop .stat-card.sort-active {
    box-shadow: var(--shadow-soft);
}

body.ios18-desktop .filter-bar {
    border-radius: var(--r-card-ios18-sm);
    border-color: var(--border-glass);
    box-shadow: none;
}

body.ios18-desktop .filter-search {
    border-radius: var(--r-pill-ios18);
}

body.ios18-desktop .filter-select,
body.ios18-desktop .filter-toggle-btn,
body.ios18-desktop .filter-clear {
    border-radius: var(--r-pill-ios18);
    transition: background-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}
body.ios18-desktop .filter-toggle-btn:active,
body.ios18-desktop .filter-clear:active {
    transform: scale(0.97);
}


/* ============================================================
 * 6. Hero / home tiles + pipeline pills
 * ============================================================ */
body.ios18-desktop .home-card {
    border-radius: var(--r-card-ios18);
    border-color: var(--border-glass);
    box-shadow: none;
    transition: box-shadow 200ms ease;
}
body.ios18-desktop .home-card:hover {
    box-shadow: var(--shadow-soft);
}

body.ios18-desktop .home-tile {
    border-radius: var(--r-card-ios18-sm);
    border-color: var(--border-glass);
    box-shadow: none;
    transition: box-shadow 200ms ease, transform 200ms ease;
}
body.ios18-desktop .home-tile:hover {
    box-shadow: var(--shadow-soft);
    transform: translateY(-1px);
}

body.ios18-desktop .home-pipeline-pill {
    border-radius: var(--r-pill-ios18);
    border-color: var(--border-glass);
    transition: background-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}
body.ios18-desktop .home-pipeline-pill:hover {
    box-shadow: var(--shadow-soft);
}
body.ios18-desktop .home-pipeline-pill:active {
    transform: scale(0.98);
}


/* ============================================================
 * 7. Popovers / menus — full glass
 * ============================================================ */
body.ios18-desktop .alerts-popover {
    background: var(--surface-glass-strong);
    backdrop-filter: blur(24px) saturate(140%);
    -webkit-backdrop-filter: blur(24px) saturate(140%);
    border-color: var(--border-glass);
    border-radius: var(--r-card-ios18);
    box-shadow: var(--shadow-pop);
}

body.ios18-desktop .alerts-popover-row {
    border-radius: 10px;
    transition: background-color 200ms ease;
}

/* The two existing user-menu placements live at body > and inside
 * .site-header — repeat both prefixes so each wins its own context. */
body.ios18-desktop body > #user-menu.user-menu,
body.ios18-desktop .site-header .create-menu.user-menu {
    background: var(--surface-glass-strong);
    backdrop-filter: blur(24px) saturate(140%);
    -webkit-backdrop-filter: blur(24px) saturate(140%);
    border-color: var(--border-glass);
    border-radius: var(--r-card-ios18-sm);
    box-shadow: var(--shadow-pop);
}

body.ios18-desktop body > #user-menu.user-menu .user-menu-item,
body.ios18-desktop .site-header .create-menu .user-menu-item {
    border-radius: 8px;
    transition: background-color 200ms ease;
}


/* ============================================================
 * 8. Buttons & chips — pill style + subtle press/hover
 * ============================================================ */
body.ios18-desktop .qa-btn {
    border-radius: var(--r-pill-ios18);
    transition: background-color 200ms ease, color 200ms ease,
                box-shadow 200ms ease, transform 200ms ease;
}
body.ios18-desktop .qa-btn:hover {
    box-shadow: var(--shadow-soft);
}
body.ios18-desktop .qa-btn:active {
    transform: scale(0.97);
}

body.ios18-desktop .import-job-btn,
body.ios18-desktop .new-job-btn,
body.ios18-desktop .doc-import-btn,
body.ios18-desktop .doc-import-btn-secondary,
body.ios18-desktop .doc-import-btn-compact {
    border-radius: var(--r-pill-ios18);
    transition: background-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}
body.ios18-desktop .import-job-btn:active,
body.ios18-desktop .new-job-btn:active,
body.ios18-desktop .doc-import-btn:active,
body.ios18-desktop .doc-import-btn-secondary:active,
body.ios18-desktop .doc-import-btn-compact:active {
    transform: scale(0.97);
}

/* Job-card chips & pills — radius bump only, no color flips */
body.ios18-desktop .jc-status-pill,
body.ios18-desktop .jc-type-pill,
body.ios18-desktop .jc-pill {
    border-radius: var(--r-pill-ios18);
}

body.ios18-desktop .jc-appt-btn,
body.ios18-desktop .jc-confirm-btn,
body.ios18-desktop .jc-map-btn {
    border-radius: var(--r-pill-ios18);
    transition: background-color 200ms ease, box-shadow 200ms ease, transform 200ms ease;
}
body.ios18-desktop .jc-appt-btn:hover,
body.ios18-desktop .jc-confirm-btn:hover,
body.ios18-desktop .jc-map-btn:hover {
    box-shadow: var(--shadow-soft);
}
body.ios18-desktop .jc-appt-btn:active,
body.ios18-desktop .jc-confirm-btn:active,
body.ios18-desktop .jc-map-btn:active {
    transform: scale(0.97);
}

/* Action panel — soft rounded panel + larger row tap targets */
body.ios18-desktop .action-panel {
    border-radius: var(--r-card-ios18-sm);
    border-color: var(--border-glass);
    box-shadow: none;
}
body.ios18-desktop .action-item {
    border-radius: 12px;
    transition: background-color 200ms ease;
}


/* ============================================================
 * 9. Tables — minor polish
 * ============================================================ */
body.ios18-desktop .data-table,
body.ios18-desktop #transactions-panel table,
body.ios18-desktop #contacts-panel table {
    border-radius: var(--r-card-ios18-sm);
    overflow: hidden;
}
body.ios18-desktop .data-table tbody tr,
body.ios18-desktop #transactions-panel table tbody tr,
body.ios18-desktop #contacts-panel table tbody tr {
    transition: background-color 200ms ease;
}


/* ============================================================
 * 10. Focus ring — iOS-style soft halo
 * ============================================================ */
body.ios18-desktop .qa-btn:focus-visible,
body.ios18-desktop .filter-toggle-btn:focus-visible,
body.ios18-desktop .filter-clear:focus-visible,
body.ios18-desktop .import-job-btn:focus-visible,
body.ios18-desktop .new-job-btn:focus-visible,
body.ios18-desktop .doc-import-btn:focus-visible,
body.ios18-desktop .doc-import-btn-secondary:focus-visible,
body.ios18-desktop .doc-import-btn-compact:focus-visible,
body.ios18-desktop .jc-appt-btn:focus-visible,
body.ios18-desktop .jc-confirm-btn:focus-visible,
body.ios18-desktop .jc-map-btn:focus-visible,
body.ios18-desktop .site-header .header-icon-btn:focus-visible {
    box-shadow: var(--shadow-focus), var(--shadow-soft);
    outline: none;
}


/* ============================================================
 * REFINEMENT PASS — quieter resting states, lighter sidebar,
 * cleaner progress, unified stats/filter band.
 *
 * Lives at the bottom of the file so it overrides the pass-1
 * declarations above at equal specificity (later in cascade).
 * Same body.ios18-desktop gate, same no-!important rule.
 * ============================================================ */

/* --- 11. Refinement tokens --------------------------------- */
body.ios18-desktop {
    /* Hairline borders are the main source of resting noise. Push the
     * existing glass border further toward transparent so cards read
     * as floating panels rather than outlined boxes. */
    --border-hairline: color-mix(in oklab, var(--border) 38%, transparent);

    /* Resting elevation is whisper-soft; the previous --shadow-soft is
     * reserved for hover. */
    --shadow-rest: 0 1px 1px rgba(15, 27, 45, 0.025),
                   0 4px 14px rgba(15, 27, 45, 0.035);
}
body.ios18-desktop[data-theme="dark"],
[data-theme="dark"] body.ios18-desktop {
    --border-hairline: color-mix(in oklab, var(--border) 50%, transparent);
    --shadow-rest:    0 1px 1px rgba(0, 0, 0, 0.30),
                      0 4px 14px rgba(0, 0, 0, 0.30);
}


/* --- 12. Job cards — quieter resting state ---------------- */
body.ios18-desktop .job-card {
    border-color: var(--border-hairline);
}

/* Tighten the header padding by 2px on each side. The original
 * .job-card .job-header is (0,1,1); this prefix adds (0,1,0). */
body.ios18-desktop .job-card .job-header {
    padding: 12px 14px;
    column-gap: 12px;
    row-gap: 8px;
}

/* Hover swaps the header tint to something quieter than the existing
 * rgba(41,104,166,0.035) — flat surface-hover reads less "blue wash". */
body.ios18-desktop .job-card .job-header:hover {
    background: color-mix(in oklab, var(--surface-hover) 60%, transparent);
}

/* Drop the 1-px transform on hover; keep the soft shadow only.
 * Cleaner because the card "lights up" without shifting position. */
body.ios18-desktop .job-card:hover {
    transform: none;
    box-shadow: var(--shadow-rest);
}

/* Repeat the .is-expanded chain so we don't undo its anchored layout. */
body.ios18-desktop .job-card.is-expanded {
    border-color: var(--border-hairline);
}


/* --- 13. Progress area — thinner, calmer ------------------ */

/* Bar: 6px → 4px and a single accent fill (no blue→green gradient). */
body.ios18-desktop .jc-bar-wrap {
    height: 4px;
    border-radius: 999px;
    background: color-mix(in oklab, var(--border) 55%, transparent);
}
body.ios18-desktop .jc-bar-fill {
    background: var(--accent-ios18);
    border-radius: 999px;
}

/* Rail dots: 10px → 8px, lines fade into the surface, halos lose
 * intensity. The colored dots themselves stay (status meaning).  */
body.ios18-desktop .jc-rail {
    height: 10px;
}
body.ios18-desktop .jc-rail-node {
    width: 8px;
    height: 8px;
}
body.ios18-desktop .jc-rail-line {
    height: 1px;
    background: color-mix(in oklab, var(--border) 50%, transparent);
}

/* Repeat the .current / .overdue chains so the existing 2px halos
 * shrink to a softer 1px ring rather than disappearing. */
body.ios18-desktop .jc-rail-node.current {
    box-shadow: 0 0 0 1px rgba(46, 117, 182, 0.18);
}
body.ios18-desktop .jc-rail-node.overdue {
    box-shadow: 0 0 0 1px rgba(192, 57, 43, 0.18);
}
body.ios18-desktop[data-theme="dark"] .jc-rail-node.current,
[data-theme="dark"] body.ios18-desktop .jc-rail-node.current {
    box-shadow: 0 0 0 1px rgba(74, 144, 217, 0.24);
}
body.ios18-desktop[data-theme="dark"] .jc-rail-node.overdue,
[data-theme="dark"] body.ios18-desktop .jc-rail-node.overdue {
    box-shadow: 0 0 0 1px rgba(231, 76, 60, 0.24);
}


/* --- 14. Sidebar — softer active, lighter rows ------------ */

/* Resting rows get a slightly subtler text color and lighter weight.
 * Original is var(--ink-muted) / 500; we drop one notch. */
body.ios18-desktop .sidebar-row {
    color: var(--ink-subtle);
    font-weight: 450;
}
body.ios18-desktop .sidebar-row:hover {
    background: color-mix(in oklab, var(--surface-hover) 70%, transparent);
    color: var(--ink);
}

/* Active row: thinner accent text weight, softer background.
 * Repeat .is-active so we tie the existing rule, not the base row. */
body.ios18-desktop .sidebar-row.is-active {
    background: color-mix(in oklab, var(--accent-soft) 60%, transparent);
    font-weight: 550;
}

/* Active indicator: 3px navy bar → 2px, color-mixed to ~70% accent.
 * The original ::before lives at (0,2,1); our prefix wins at (0,3,1). */
body.ios18-desktop .sidebar-row.is-active::before {
    width: 2px;
    background: color-mix(in oklab, var(--accent) 70%, transparent);
    top: 10px;
    bottom: 10px;
}

/* Sidebar icons keep their accent on the active row but fade slightly
 * on resting rows for a cleaner overall density. */
body.ios18-desktop .sidebar-row-icon {
    opacity: 0.78;
}
body.ios18-desktop .sidebar-row.is-active .sidebar-row-icon,
body.ios18-desktop .sidebar-row:hover .sidebar-row-icon {
    opacity: 1;
}


/* --- 15. Stats + filter bar — one coherent panel band ----- */

/* Drop the visible borders so the band reads as a continuous surface.
 * Keep the surface bg + radius intact. No resting shadow — the cards
 * float on whitespace alone, and only get a whisper of shadow on hover. */
body.ios18-desktop .stats-bar .stat-card,
body.ios18-desktop .stat-card {
    border-color: transparent;
    background: var(--surface);
}
body.ios18-desktop .stat-card:hover {
    box-shadow: var(--shadow-rest);
    border-color: var(--border-hairline);
    transform: none; /* refinement: no lift, just a quiet shadow */
}

/* sort-active: lose the heavy border, keep the accent-only label
 * (set by an existing 07-desktop.css rule we don't touch) and add a
 * faint accent wash so the active state still reads. */
body.ios18-desktop .stat-card.sort-active {
    border-color: transparent;
    background: color-mix(in oklab, var(--accent-soft) 35%, var(--surface));
    box-shadow: none;
}

body.ios18-desktop .filter-bar {
    border-color: transparent;
    background: var(--surface);
}

/* Filter inputs share the band feel: the existing surface-sunken bg
 * is what makes them stand out; soften the contrast by a touch. */
body.ios18-desktop .filter-search,
body.ios18-desktop .filter-select {
    border-color: var(--border-hairline);
    background-color: color-mix(in oklab, var(--surface-sunken) 70%, var(--surface));
}
body.ios18-desktop .filter-search:focus,
body.ios18-desktop .filter-select:focus {
    border-color: var(--accent);
}


/* ============================================================
 * DECLUTTER PASS — collapsed job-card density reduction.
 *
 * Every rule is gated on `:not(.is-expanded)` so the expanded
 * card keeps every detail. Functionality stays — buttons remain
 * in the DOM and tappable; secondary surfaces just fade out.
 *
 * Cascade-last so it overrides earlier passes at equal specificity.
 * No layout/grid restructuring; only spacing, opacity, display
 * toggles, and a single `:has()` reveal for the BALANCE row.
 * ============================================================ */

/* --- 16. Collapsed job-card — show BALANCE only ---------- */

/* Hide every fin-stack row by default, then unhide just the row
 * containing .balance. `:has()` is supported in all evergreens
 * (Safari 15.4+, Chrome 105+, FF 121+) — same browsers iOS18 already
 * targets via backdrop-filter. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-fin-stack .jc-fin-line {
    display: none;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-fin-stack .jc-fin-line:has(.jc-fin-val.balance) {
    display: flex;
    margin-top: 0;
}

/* Drop the "BALANCE" label inside the surviving row — value alone
 * carries enough meaning at this density. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-fin-stack .jc-fin-line .jc-fin-lbl {
    display: none;
}

/* Promote the BALANCE number to the visual headline of the right
 * column. Bigger type, tabular alignment kept. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-fin-stack .jc-fin-val.balance {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.1;
}


/* --- 17. Address line — fold city away --------------------
 *
 * `.jc-city` lives in its own grid row underneath `.jc-addr`. On
 * collapsed cards it duplicates info the user already infers from
 * the address text. Hide it (the expanded view still shows it). */
body.ios18-desktop .job-card:not(.is-expanded) .jc-city {
    display: none;
}

/* Job-number row reads as a chrome detail rather than data — drop
 * its weight so the eye lands on the title, address, and balance. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-jobnum {
    opacity: 0.55;
    font-weight: 500;
}


/* --- 18. Progress row — pct pill is the headline --------- */

/* Suppress the rail entirely on collapsed cards. The expanded card
 * has the full vertical timeline, so this isn't lost — just deferred.
 * `height: 0` removes flow weight; `overflow: hidden` cleans the dots. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-rail {
    display: none;
}

/* The progress row holds: badge pill, state pill, pct pill, rail.
 * With the rail gone, let the row sit flush with the row above. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-progress-row {
    gap: 6px;
}


/* --- 19. Bottom actions — primary stays, secondary fade -- */

/* Map is the least-frequently-tapped of the three. Drop its weight
 * to ~40% at rest; full opacity returns when the card is hovered.
 * Confirm stays prominent because it's only rendered when there's
 * an active appointment confirmation to send. Appt stays prominent
 * because it's the most-used field action. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-map-btn {
    opacity: 0.45;
    transition: opacity 200ms ease, background-color 200ms ease,
                box-shadow 200ms ease, transform 200ms ease;
}
body.ios18-desktop .job-card:not(.is-expanded):hover .jc-map-btn,
body.ios18-desktop .job-card:not(.is-expanded) .jc-map-btn:hover,
body.ios18-desktop .job-card:not(.is-expanded) .jc-map-btn:focus-visible {
    opacity: 1;
}


/* --- 20. Tighter grouping, more air between groups -------
 *
 * The header is a CSS grid; we don't touch its track template, only
 * row-gap (between groups) and the divider that visually splits them.
 * The hr divider becomes redundant once spacing is increased — hide. */
body.ios18-desktop .job-card:not(.is-expanded) .job-header {
    row-gap: 12px;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-divider {
    display: none;
}

/* Pull the bottom row close to the progress row above it so they
 * read as one "status + next-action" cluster, separated from the
 * identity/finance cluster by the larger row-gap. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-bottom {
    margin-top: -2px;
}


/* ============================================================
 * DECLUTTER PASS 2 — quieter secondaries on collapsed cards.
 *
 * Targets surfaces the previous declutter pass left at full
 * strength: timestamp meta line, the two progress pills, kebab,
 * and re-balances the Map button after pass-3's heavier dim.
 *
 * Scope unchanged: body.ios18-desktop .job-card:not(.is-expanded).
 * Expanded cards keep all defaults. No HTML changes.
 * ============================================================ */

/* --- 21. Timestamp meta line ----------------------------- *
 * `.jc-timestamps` renders "Created … · Estimate v1 … · Updated …".
 * In the iOS mock this kind of metadata sits as quiet sub-text. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-timestamps {
    opacity: 0.55;
    font-size: 11px;
    font-weight: 400;
    letter-spacing: 0;
}


/* --- 22. Progress pills — calmer ------------------------- */

/* Percent pill: keep its neutral grey tone, just lose the visible
 * border and drop one weight notch so it reads as a soft data
 * marker, not a label-shouting capsule. Original is 700; 600
 * still preserves all-caps legibility at 10px. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-pill-pct {
    border-color: transparent;
    font-weight: 600;
}

/* State pill (e.g. "ACCEPTANCE / DEPOSIT RECEIVED"). The colored
 * background carries the meaning — the saturated 1px border is
 * what makes it dominate. Drop the border and clamp the width so
 * long labels truncate instead of stealing the whole row.
 *
 * Background color stays untouched per state-modifier; specificity
 * (0,4,1) > existing (0,2,0) variants but I only set border + size,
 * so .progress-ready / .progress-permit etc. still color the bg. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-pill-state {
    border-color: transparent;
    font-weight: 600;
    max-width: 16ch;
    overflow: hidden;
    text-overflow: ellipsis;
}


/* --- 23. Actions — re-balance ---------------------------- */

/* Map: pass-3 set this to 0.45, which read as too dim — the user
 * asked for "usable, just secondary". 0.65 keeps it reachable. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-map-btn {
    opacity: 0.65;
}

/* Kebab is the "more actions" affordance — true secondary. Fades
 * to half until the card or the button itself is hovered/focused.
 * Keeps tap targets full-size; only the visual weight drops. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-kebab {
    opacity: 0.5;
    transition: opacity 200ms ease, color 200ms ease;
}
body.ios18-desktop .job-card:not(.is-expanded):hover .jc-kebab,
body.ios18-desktop .job-card:not(.is-expanded) .jc-kebab:hover,
body.ios18-desktop .job-card:not(.is-expanded) .jc-kebab:focus-visible {
    opacity: 1;
}


/* ============================================================
 * DECLUTTER PASS 3 — single primary header pill, thin progress
 * bar, hover-revealed secondary actions.
 *
 * Pairs with one HTML change in job-card.js:
 *   <div class="jc-progress-row" style="--jc-pct: X%">
 * which feeds the bar fill width below.
 *
 * Scope unchanged: body.ios18-desktop .job-card:not(.is-expanded).
 * Expanded cards keep all defaults.
 * ============================================================ */

/* --- 24. Identity row — drop the job number ----------------
 * Pass-3 dimmed `.jc-jobnum` to 0.55 opacity. At iOS-mock density
 * the row is still net noise — hide it on collapsed cards. The
 * expanded card still shows it. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-jobnum {
    display: none;
}


/* --- 25. Header status pill — keep type pill only ----------
 * `.jc-type-pill` (e.g. "Work Order", "EV Charger Install") sits
 * with the identity block — it stays as the ONE primary pill.
 * `.jc-pill-state` (the loud "ACCEPTANCE / DEPOSIT RECEIVED"
 * orange pill) lives in the progress row and is the heaviest
 * remaining source of color noise — hide it on collapsed. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-pill-state {
    display: none;
}


/* --- 26. Progress — thin iOS bar + percent -----------------
 * The row gets a 3px translucent track at top, then a colored
 * fill of width `var(--jc-pct, 0%)` from the inline style we
 * inject in job-card.js. The pct pill stays as the textual
 * readout next to the bar. Old rail rule (display:none) from
 * pass-3 still applies. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-progress-row {
    position: relative;
    padding-top: 12px;
    align-items: center;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-progress-row::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    border-radius: 999px;
    background: color-mix(in oklab, var(--border) 55%, transparent);
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-progress-row::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    height: 3px;
    width: var(--jc-pct, 0%);
    border-radius: 999px;
    background: var(--accent);
    transition: width 200ms ease;
}


/* --- 27. Bottom actions — hover-revealed -------------------
 * The whole `.jc-bottom-actions` cluster (Send Confirmation,
 * +Appointment, Map) fades to 0 / pointer-events:none at rest;
 * card hover and any inner :focus-visible reveal them. Tab
 * focus through the buttons still triggers the reveal because
 * the parent picks up :focus-within from the focused child.
 *
 * `.jc-next-line` (sibling of `.jc-bottom-actions` inside the
 * `.jc-bottom` row) stays visible — it carries the next-action
 * sentence, which is informational text, not an action button.
 *
 * The OPEN button (`.jc-expand-desktop`) lives in `.jc-meta-top`
 * — outside `.jc-bottom-actions` — so it stays visible always.
 * Pass-2 .jc-map-btn opacity (0.65) is overridden here with 0
 * because it's now a strict reveal-on-hover surface. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-bottom-actions > * {
    opacity: 0;
    pointer-events: none;
    transform: translateX(4px);
    transition: opacity 200ms ease, transform 200ms ease;
}
body.ios18-desktop .job-card:not(.is-expanded):hover .jc-bottom-actions > *,
body.ios18-desktop .job-card:not(.is-expanded):focus-within .jc-bottom-actions > * {
    opacity: 1;
    pointer-events: auto;
    transform: none;
}


/* ============================================================
 * MOCK PARITY PASS — full alignment with is18_card.png brief.
 *
 * Pairs with three small additions in job-card.js:
 *   - .jc-ios-subtitle  (combined "street • city" line)
 *   - .jc-ios-pct       (right-column percent under BALANCE)
 *   - .jc-ios-updated   ("Updated Nd ago" in the bottom row)
 * Each new element ships with the `hidden` attribute so default
 * (non-iOS18) views are unchanged.
 *
 * Color tokens are taken straight from the mock spec — light:
 * #FFFFFF / #FAFAFC surfaces, rgba(0,0,0,0.06) hairline,
 * #6E6E73 muted text, #007AFF accent. Dark uses the matching
 * iOS dark system tokens (#1C1C1E / #2C2C2E / #98989D / #0A84FF).
 * ============================================================ */

/* --- 28. iOS 18 system tokens ------------------------------ */
body.ios18-desktop {
    --ios18-accent:   #007AFF;
    --ios18-muted:    #6E6E73;
    --ios18-hairline: rgba(0, 0, 0, 0.04);
    --ios18-surface-1: #FFFFFF;
    --ios18-surface-2: #FAFAFC;
}
body.ios18-desktop[data-theme="dark"],
[data-theme="dark"] body.ios18-desktop {
    --ios18-accent:   #0A84FF;
    --ios18-muted:    #98989D;
    --ios18-hairline: rgba(255, 255, 255, 0.05);
    --ios18-surface-1: #1C1C1E;
    --ios18-surface-2: #2C2C2E;
}


/* --- 29. Hide everything not in the mock (collapsed only) -- *
 * Sweeping `display: none` for all the surfaces the mock omits.
 * These outrank the v1–v5 declarations because they're later in
 * the same file at equal specificity. No !important. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-type-pill,
body.ios18-desktop .job-card:not(.is-expanded) .jc-progress-row,
body.ios18-desktop .job-card:not(.is-expanded) .jc-bottom-actions,
body.ios18-desktop .job-card:not(.is-expanded) .jc-timestamps,
body.ios18-desktop .job-card:not(.is-expanded) .jc-kebab,
body.ios18-desktop .job-card:not(.is-expanded) .jc-addr {
    display: none;
}
/* `.jc-city`, `.jc-jobnum`, `.jc-divider`, `.jc-rail`, the v5 progress
 * bar pseudo-elements all already become invisible because their
 * parents (`.jc-progress-row`) are now hidden, OR because earlier
 * passes hid them directly. */


/* --- 30. Reveal iOS 18 elements (override the `hidden` attr) --- *
 * The `[hidden]` UA rule is `display: none` at (0,1,0). Our
 * `body.ios18-desktop … .jc-ios-subtitle` is (0,3,1) — wins. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-ios-subtitle {
    display: block;
    color: var(--ios18-muted);
    font-size: 13px;
    line-height: 1.35;
    margin-top: 2px;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-ios-pct {
    display: block;
    color: var(--ios18-accent);
    font-size: 13px;
    font-weight: 600;
    text-align: right;
    line-height: 1.2;
    margin-top: 4px;
    font-variant-numeric: tabular-nums;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-ios-updated {
    display: inline-flex;
    color: var(--ios18-muted);
    font-size: 12px;
    line-height: 1.2;
    margin-right: auto;
}


/* --- 31. Open button → small icon-only ghost --------------- *
 * Hide the "Open"/"Close" text labels, shrink padding, give it
 * a hairline ghost border. Icon (existing 4-corner-arrows SVG)
 * stays. Click area unchanged. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-expand-desktop {
    padding: 6px;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: transparent;
    border: 1px solid var(--ios18-hairline);
    color: var(--ios18-muted);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-expand-desktop:hover {
    background: var(--ios18-surface-2);
    color: var(--ios18-accent);
    border-color: color-mix(in oklab, var(--ios18-accent) 30%, transparent);
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-expand-desktop .jc-expand-label {
    display: none;
}


/* --- 32. Card surface — mock spec --------------------------- */
body.ios18-desktop .job-card:not(.is-expanded) {
    background: var(--ios18-surface-1);
    border-color: var(--ios18-hairline);
    border-radius: 18px;
}
body.ios18-desktop .job-card:not(.is-expanded):hover {
    background: var(--ios18-surface-2);
    border-color: var(--ios18-hairline);
}


/* --- 33. Bottom row — Updated left, Next: right ------------ *
 * `.jc-bottom` is the only flex row left in the bottom area
 * after pass-3 hid the divider. Force it to space-between and
 * mute the text. Calendar emoji (`.jc-next-icon`) is hidden —
 * the mock is text-only. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-bottom {
    justify-content: space-between;
    align-items: baseline;
    color: var(--ios18-muted);
    opacity: 0.85;
    font-size: 12px;
    margin-top: 8px;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-next-line {
    color: var(--ios18-muted);
    font-size: 12px;
    font-weight: 400;
    flex: 0 1 auto;
    min-width: 0;
    text-align: right;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-next-icon {
    display: none;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-next-line strong {
    color: var(--ios18-muted);
    font-weight: 500;
}


/* --- 34. Right-column meta — center the BALANCE stack ------ *
 * With the right-column now showing only [icon] + BALANCE + %,
 * push the balance group toward the vertical middle so it
 * aligns with the title in the left column. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-meta {
    justify-content: flex-start;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-fin-stack {
    margin-top: auto;
    align-self: flex-end;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-ios-pct {
    align-self: flex-end;
    margin-bottom: auto;
}


/* --- 35. Title weight — match the mock --------------------- */
body.ios18-desktop .job-card:not(.is-expanded) .jc-client-name {
    font-weight: 600;
    font-size: 16px;
    color: var(--ink);
    letter-spacing: -0.01em;
}


/* --- 36. Soften card hover transition (100–200ms per spec) -- */
body.ios18-desktop .job-card:not(.is-expanded) {
    transition: background-color 200ms ease,
                border-color 200ms ease,
                box-shadow 200ms ease;
}


/* ============================================================
 * FINAL POLISH PASS — close button, ghost OPEN, ambient bar.
 *
 * Pairs with one HTML change: the inline `--jc-pct: X%` style
 * was moved up from `.jc-progress-row` (now hidden) to the
 * `.job-card` element so the bar pseudo below can read it.
 * ============================================================ */

/* --- 37. Expanded close — top-right circular ✕ -------------- *
 *
 * Override the existing 520×52 bottom-fixed close pill defined at
 * `.job-card.is-expanded .jc-expand` (08-cards-v2.css:168).
 *
 * Specificity: existing chain is (0,2,0); adding `body.ios18-desktop`
 * lifts ours to (0,3,1). Wins without !important. Same rule for the
 * :active state — existing `.job-card.is-expanded .jc-expand:active`
 * (0,2,1) is beaten by ours at (0,3,2).
 *
 * Functionality preserved: same `.jc-expand` button, same onclick
 * binding (`toggleJob(jn)`). Only chrome and position change. */
body.ios18-desktop .job-card.is-expanded .jc-expand {
    position: fixed;
    top: calc(env(safe-area-inset-top, 0px) + 16px);
    right: 20px;
    bottom: auto;
    left: auto;
    width: 30px;
    height: 30px;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: transparent;
    box-shadow: none;
    color: var(--ios18-muted, var(--ink-subtle));
    opacity: 0.45;
    transform: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: opacity 200ms ease, color 200ms ease, background-color 200ms ease;
}
body.ios18-desktop .job-card.is-expanded .jc-expand:hover {
    opacity: 0.85;
    background: color-mix(in oklab, var(--ink) 8%, transparent);
}
body.ios18-desktop .job-card.is-expanded .jc-expand:active {
    transform: scale(0.94);
}

/* Replace the 4-corner-arrows SVG and "Close" label with a clean ✕. */
body.ios18-desktop .job-card.is-expanded .jc-expand svg,
body.ios18-desktop .job-card.is-expanded .jc-expand .jc-expand-label {
    display: none;
}
body.ios18-desktop .job-card.is-expanded .jc-expand::before {
    content: "✕";
    font-size: 16px;
    font-weight: 500;
    line-height: 1;
}


/* --- 38. OPEN button — true ghost, no border --------------- *
 *
 * Pass-6 §31 set a 1px hairline border on the collapsed-card OPEN
 * button. Per spec it should read as a ghost: no border, subtle
 * presence at rest, full presence on hover. Keep size + 4-corner
 * SVG icon untouched. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-expand-desktop {
    border: none;
    background: transparent;
    opacity: 0.45;
    transition: opacity 200ms ease, background-color 200ms ease, color 200ms ease;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-expand-desktop:hover {
    opacity: 0.85;
    background: color-mix(in oklab, var(--ink) 6%, transparent);
    color: var(--ios18-accent);
    border-color: transparent;
}


/* --- 39. Ambient progress bar — thin, low-contrast --------- *
 *
 * Pass-6 hid `.jc-progress-row` entirely, which dropped the v5
 * thin bar with it. Restore as a single pseudo on `.job-card`
 * (no extra HTML, no new pills). Reads `--jc-pct` from the inline
 * style on the card.
 *
 * `position: relative` is needed on the card for the absolute
 * pseudo. Other passes don't already set this so we're safe. */
body.ios18-desktop .job-card:not(.is-expanded) {
    position: relative;
}
body.ios18-desktop .job-card:not(.is-expanded)::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    width: var(--jc-pct, 0%);
    max-width: 100%;
    background: color-mix(in oklab, var(--ios18-accent) 15%, transparent);
    border-bottom-left-radius: 18px;
    pointer-events: none;
    transition: width 200ms ease;
}


/* --- 40. Thumbnail — let the text lead -------------------- *
 *
 * Slight desaturation + soft opacity so the photo reads as
 * supporting context rather than the primary visual anchor.
 * Hover restores full chroma so the user can confirm it's the
 * job's actual reference photo. Collapsed only. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-thumb {
    opacity: 0.92;
    filter: saturate(0.92);
    transition: opacity 200ms ease, filter 200ms ease;
}
body.ios18-desktop .job-card:not(.is-expanded):hover .jc-thumb,
body.ios18-desktop .job-card:not(.is-expanded) .jc-thumb:hover {
    opacity: 1;
    filter: saturate(1);
}


/* ============================================================
 * SINGLE-COLUMN LIST PASS — collapsed-only.
 *
 * Convert the desktop multi-column card grid into a vertical
 * iOS-style list. Match the mobile information density: small
 * square thumbnail on the left, content stacks right, full
 * width per card, ~8px gap between cards.
 *
 * No HTML changes. Re-uses elements already in the markup that
 * were hidden on desktop (`.jc-list-type-number`, `.jc-timestamps`)
 * and hides the iOS18-only elements that conflicted with the new
 * stacked layout (`.jc-ios-pct`, `.jc-ios-updated`).
 *
 * Expanded card untouched — every selector includes
 * `:not(.is-expanded)`.
 * ============================================================ */

/* --- 41. List container — single column, tight gap --------- *
 *
 * Existing `.job-section-cards` is `grid-template-columns:
 * repeat(2, minmax(0,1fr)); gap: 18px;` (08-cards-v2.css:1004,
 * inside the wide-desktop media query). Override to one column,
 * 8px gap. Specificity: `body.ios18-desktop .job-section-cards`
 * (0,2,1) > existing (0,1,0). */
body.ios18-desktop .job-section-cards {
    grid-template-columns: 1fr;
    gap: 8px;
}


/* --- 42. Card header — 88px thumb + content stack --------- *
 *
 * Override the desktop 3-column 5-row grid (`140px 1fr auto` /
 * 5 rows) with a tight 2-column auto-flow. Thumbnail spans all
 * rows; content children flow in column 2 in DOM order. */
body.ios18-desktop .job-card:not(.is-expanded) .job-header {
    grid-template-columns: 88px minmax(0, 1fr);
    grid-template-rows: auto;
    column-gap: 14px;
    row-gap: 4px;
    padding: 10px 14px;
    min-height: 0;
    align-items: start;
}

/* Larger square thumbnail per "as large as possible" pass; clears
 * the 180px desktop min-height the classic card grid set. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-thumb {
    width: 88px;
    height: 88px;
    min-height: 0;
    grid-column: 1;
    grid-row: 1 / -1;
    align-self: start;
}

/* Identity column — tight vertical rhythm matching mobile. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-identity {
    grid-column: 2;
    gap: 2px;
}


/* --- 43. Lift `.jc-meta` children into grid layout --------- *
 *
 * `display: contents` makes `.jc-meta`'s box vanish for layout
 * purposes — its children become direct grid items of `.job-header`
 * and pick up the same column placement. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-meta {
    display: contents;
}

/* OPEN button + kebab cluster floats top-right (out of grid flow). */
body.ios18-desktop .job-card:not(.is-expanded) .jc-meta-top {
    position: absolute;
    top: 8px;
    right: 12px;
    z-index: 2;
}

/* BALANCE row flows in column 2 right after the identity stack.
 * Override §16's 22px / §34's flex-end alignment with list-friendly
 * values: smaller font, top-aligned, small margin from timestamps. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-fin-stack {
    grid-column: 2;
    margin-top: 4px;
    align-self: start;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-fin-stack .jc-fin-val.balance {
    font-size: 16px;
}

/* Bottom row (Next: line) — last row in column 2, left-aligned. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-bottom {
    grid-column: 2;
    margin-top: 2px;
    justify-content: flex-start;
}


/* --- 44. Re-show mobile-list elements ---------------------- *
 *
 * `.jc-list-type-number` ("Work Order • #2551") and `.jc-timestamps`
 * ("Created … · Estimate … · Updated …") were hidden by the base
 * mobile-codex rule and by §29 of pass 6 respectively. We want
 * them back as the type+# row and the meta line. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-list-type-number {
    display: block;
    color: var(--ios18-muted);
    font-size: 12px;
    font-weight: 500;
}
body.ios18-desktop .job-card:not(.is-expanded) .jc-timestamps {
    display: block;
    opacity: 0.55;
    font-size: 11px;
    line-height: 1.35;
    margin-top: 2px;
}


/* --- 45. Hide elements that conflict with the new layout --- *
 *
 * `.jc-ios-pct` (right-column percent) and `.jc-ios-updated`
 * (bottom-row "Updated Nd ago") were both layout helpers for the
 * earlier two-column iOS18 design. The single-column list shows
 * the percentage via the ambient bar pseudo and the Updated info
 * via the full timestamps line. Hide the redundant ones. */
body.ios18-desktop .job-card:not(.is-expanded) .jc-ios-pct,
body.ios18-desktop .job-card:not(.is-expanded) .jc-ios-updated {
    display: none;
}


/* --- 46. Title size for list density ----------------------- */
body.ios18-desktop .job-card:not(.is-expanded) .jc-client-name {
    font-size: 15px;
}


/* --- 47. Slightly tighter container side padding ----------- *
 *
 * 07-desktop.css gives `.main-wrap` `padding: … var(--sp-8) …`
 * (32px sides). Trim to `var(--sp-5)` (20px) so cards sit closer
 * to the column edges, matching iOS list ergonomics. */
body.ios18-desktop .main-wrap {
    padding-left: var(--sp-5);
    padding-right: var(--sp-5);
}


/* --- 48. Per-card rounded cards, tight stack -------------- *
 *
 * Each card keeps its own rounded shape (all four corners),
 * full width of the section column, and stacks tightly with a
 * small 4px gap so adjacent rounded shapes don't visually
 * collide.
 *
 * The desktop default `margin-bottom: var(--sp-4)` (~16px) on
 * `.job-card` from `07-desktop.css:866` is what produced the
 * big gap — overriding it to 4px gives a tight rhythm without
 * losing the "card" feel. The base `max-width: 720px` is
 * dropped so cards fill the column. */

/* Wrapper: simple flex column, no own surface chrome. */
body.ios18-desktop .job-section-cards {
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: transparent;
    border: none;
    border-radius: 0;
    overflow: visible;
}

/* Card: rounded all four corners, hairline border, full width. */
body.ios18-desktop .job-card:not(.is-expanded) {
    margin-bottom: 0;
    max-width: none;
    width: 100%;
    background: var(--ios18-surface-1);
    border: 1px solid var(--ios18-hairline);
    border-radius: 18px;
    box-shadow: none;
}

/* Hover-tint the card surface (subtle, iOS-like). */
body.ios18-desktop .job-card:not(.is-expanded):hover {
    background: var(--ios18-surface-2);
}

/* Ambient progress bar curves with the card's rounded bottom. */
body.ios18-desktop .job-card:not(.is-expanded)::after {
    border-bottom-left-radius: 18px;
}


/* --- 49. Expanded card matches collapsed-card width -------- *
 *
 * The base `.job-card { max-width: 720px }` (08-cards-v2.css:5)
 * caps every card at 720px. In v13 we overrode that for collapsed
 * cards so they fill the section column. The expanded card was
 * still capped — making it visibly narrower than the list it
 * came from. Drop the cap on expanded too so the open card spans
 * the same width as the closed ones did. */
body.ios18-desktop .job-card.is-expanded {
    max-width: none;
    width: 100%;
}


/* ============================================================
 * 24. iOS 18 / Keynote-style glass menus (desktop only)
 *
 * Refines the new top-of-page filter/search pills + the popover
 * surfaces to match an iOS 18 context menu / Keynote inspector:
 *   - dark translucent navy/black panel
 *   - heavy backdrop blur with subtle saturation lift
 *   - 26-32px corner radii
 *   - thin 0.5px hairline + soft inset highlight as the only border
 *   - subtle shadow only — no harsh drop
 *   - destructive Clear filters in iOS red
 *   - 200ms ease transitions on row hover and panel open/close
 *
 * All declarations are scoped to body.ios18-desktop so the existing
 * mobile rules in 01-base.css and 09-mobile-codex.css are untouched.
 * ============================================================ */

/* Local glass tokens — adaptive material, dark variant. Single base
 * color (no stacked gradients), one inset top highlight, soft drop. */
body.ios18-desktop {
    --ios18-menu-bg:        rgba(30, 30, 40, 0.40);
    --ios18-menu-blur:      blur(30px) saturate(170%);
    --ios18-menu-border:    rgba(255, 255, 255, 0.18);
    --ios18-menu-inset:     inset 0 1px 0 rgba(255, 255, 255, 0.25);
    --ios18-menu-shadow:    0 12px 40px rgba(0, 0, 0, 0.24);
    --ios18-menu-text:      rgba(255, 255, 255, 0.94);
    --ios18-menu-text-mute: rgba(255, 255, 255, 0.55);
    --ios18-menu-sep:       rgba(255, 255, 255, 0.10);
    --ios18-menu-hover:     rgba(255, 255, 255, 0.06);
    --ios18-menu-press:     rgba(255, 255, 255, 0.10);
    --ios18-menu-danger:    #FF453A;
    --ios18-backdrop:       rgba(0, 0, 0, 0.12);
}

/* ── Top-of-page jobs action pills + search field ───────────── */
body.ios18-desktop .jobs-page-actions {
    padding: 16px 24px 8px;
}
body.ios18-desktop .jobs-action-pill {
    width: 36px;
    height: 36px;
    background: var(--surface-glass);
    border: 0.5px solid var(--border-glass);
    color: var(--text);
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
    transition: background-color 200ms ease, border-color 200ms ease,
                transform 200ms ease, box-shadow 200ms ease;
}
body.ios18-desktop .jobs-action-pill:hover,
body.ios18-desktop .jobs-action-pill:focus-visible {
    background: var(--surface-glass-strong);
    box-shadow: var(--shadow-soft);
    outline: none;
}
body.ios18-desktop .jobs-action-pill:active { transform: scale(0.96); }
body.ios18-desktop .jobs-action-search-field {
    background: var(--surface-glass);
    border: 0.5px solid var(--border-glass);
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
    box-shadow: var(--shadow-soft);
    transition: background-color 200ms ease, border-color 200ms ease;
}
body.ios18-desktop .jobs-action-search-field:focus-within {
    background: var(--surface-glass-strong);
    border-color: color-mix(in oklab, var(--accent-ios18) 50%, transparent);
}

/* ── Filter popup (.jobs-more-menu) — true iOS frosted glass ─── */
body.ios18-desktop .jobs-more-menu {
    /* Adaptive frosted glass — single base color, one inset top
     * highlight, soft drop. Page content is visibly blurred through. */
    background: var(--ios18-menu-bg);
    -webkit-backdrop-filter: var(--ios18-menu-blur);
    backdrop-filter: var(--ios18-menu-blur);
    border: 1px solid var(--ios18-menu-border);
    border-radius: 28px;
    box-shadow: var(--ios18-menu-shadow), var(--ios18-menu-inset);
    color: var(--ios18-menu-text);
    transition: opacity 200ms ease, transform 200ms ease;
    transform-origin: top center;
}
/* When the menu is hidden, give it the slight scale-from-top so showing
 * via JS (toggling [hidden]) animates in. */
body.ios18-desktop .jobs-more-menu[hidden] {
    /* keep [hidden] hiding the panel — only the visible state animates */
    display: none;
}
body.ios18-desktop .jobs-more-menu .jobs-more-section + .jobs-more-section {
    border-top: 8px solid transparent;
    box-shadow: inset 0 1px 0 var(--ios18-menu-sep);
}
body.ios18-desktop .jobs-more-menu .jobs-more-row {
    padding: 16px 22px;
    gap: 16px;
    transition: background-color 200ms ease;
}
body.ios18-desktop .jobs-more-menu .jobs-more-row + .jobs-more-row::before {
    /* Match the icon column width so the hairline aligns under labels,
     * iOS-style — separator starts where the label starts. */
    left: 60px;
    background: var(--ios18-menu-sep);
}
body.ios18-desktop .jobs-more-menu .jobs-more-row:hover,
body.ios18-desktop .jobs-more-menu .jobs-more-row:focus-visible {
    background: var(--ios18-menu-hover);
    outline: none;
}
body.ios18-desktop .jobs-more-menu .jobs-more-row:active {
    background: var(--ios18-menu-press);
}
body.ios18-desktop .jobs-more-menu .jobs-more-icon {
    color: var(--ios18-menu-text);
    flex: 0 0 24px;
}
body.ios18-desktop .jobs-more-menu .jobs-more-icon svg {
    stroke-width: 1.6;
}
body.ios18-desktop .jobs-more-menu .jobs-more-label {
    font-size: 16px;
    font-weight: 500;
    color: var(--ios18-menu-text);
    letter-spacing: 0.1px;
}
body.ios18-desktop .jobs-more-menu .jobs-more-select-wrap {
    color: var(--ios18-menu-text-mute);
    font-size: 14px;
}
body.ios18-desktop .jobs-more-menu .jobs-more-select-wrap select {
    color: inherit;
}
body.ios18-desktop .jobs-more-menu .jobs-more-row-danger .jobs-more-label,
body.ios18-desktop .jobs-more-menu .jobs-more-row-danger .jobs-more-icon {
    color: var(--ios18-menu-danger);
}

/* Dim backdrop behind the menu — softer than the mobile default so the
 * desktop content stays legible behind the glass. */
body.ios18-desktop .jobs-more-backdrop {
    background: var(--ios18-backdrop);
    transition: opacity 200ms ease;
    animation: ios18-backdrop-in 200ms ease-out;
}
@keyframes ios18-backdrop-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ── Other live popovers — match the new tone ─────────────────
 * Keep them on the existing token family but bump the corner radii
 * and blur so they read as the same family of glass surfaces. */
body.ios18-desktop .alerts-popover,
body.ios18-desktop body > #user-menu.user-menu,
body.ios18-desktop .site-header .create-menu.user-menu {
    border-radius: 22px;
    backdrop-filter: blur(40px) saturate(170%);
    -webkit-backdrop-filter: blur(40px) saturate(170%);
    box-shadow: var(--ios18-menu-shadow), var(--ios18-menu-inset);
    border-color: var(--ios18-menu-border);
    transition: opacity 200ms ease, transform 200ms ease;
}
body.ios18-desktop .alerts-popover-row,
body.ios18-desktop body > #user-menu.user-menu .user-menu-item,
body.ios18-desktop .site-header .create-menu .user-menu-item {
    border-radius: 12px;
    transition: background-color 200ms ease;
}
