/* app.css — the merged CMS app layer (P3). cms + datatable + forms + modals,
 * concatenated IN CASCADE ORDER and ALL UNLAYERED so they beat the dcs.spa
 * @layers (base/site) exactly as the four separate sheets did. Load order in
 * shell.html: tokens.css -> base.css -> site.css -> app.css. Within this file the
 * order cms -> datatable -> forms -> modals preserves every specificity tie.
 * Plan: _plan/2026-06-17-css-consolidation-tokenization.md (P3). */

/* ===================================================================
   cms.css
   =================================================================== */
/* cms.css — the #content (CMS/PIM) styling layer for the dcs.spa shell.
 *
 * Part C of the Datastar webd foundation: this was a ~135-line inline <style>
 * in shell.html, re-read + re-sent on EVERY request. Externalised here so it's
 * cached (one fetch, then 304s). Only the FOUC-critical theme-preload script +
 * the body background stay inline in shell.html.
 *
 * CASCADE: these rules are INTENTIONALLY UNLAYERED. base.css declares
 * `@layer reset, tokens, base, components, utilities, animations` and any
 * unlayered rule beats every layer regardless of specificity — which is what
 * the original inline block relied on to override base.css's component layer
 * (link colour, table styling, active-sort opacity). Keeping cms.css unlayered
 * AND loaded after base.css/site.css reproduces the original behaviour exactly.
 * Do not wrap these in an @layer without re-checking every #content override. */

/* CMS content layer — scoped to #content so it never fights the dcs.spa chrome.
   Consumes the GLOBAL oklch theme tokens directly (--fg-primary / --glass /
   --border / --accent / --accent-fg) — no local palette aliases — so handler
   markup (.card/.btn/.tag, post prose, tables) is theme-aware and consistent with
   the rest of the site. (Was: --head/--card/--accent2/--afg vestigial aliases +
   a --border→--bg-tertiary remap that made content borders invisible.) */
#content{
    color: var(--fg-primary);
    /* Content column surface — one shade stronger than the sidebars (--bg-secondary)
       so the centre stands out; cards (.card = --glass) sit a shade lighter on top.
       Flips light/dark. */
    background: var(--bg-tertiary);
}
#content .cms-wrap{max-width:60rem;margin:var(--space-0) auto;padding:var(--space-9) var(--space-6) var(--space-20);font-size:1rem;line-height:1.65}
/* Content width modes (Appearance → Narrow|Normal|Wide; persisted in base-state, applied
   pre-paint as html.narrow / html.wide; Normal = no class = the 60rem default). A deliberate
   user choice — the 1.5rem side padding stays as a gutter and pinned-sidebar margins on
   <main> still apply. Narrow = ~75% of normal (a tighter reading measure); Wide drops the
   cap to fill the available real estate. Surfaces may add `html.wide …`-scoped wide-only
   layouts (multi-column prose, side-by-side editor/preview) as a follow-up — this is the hook. */
html.narrow #content .cms-wrap{max-width:calc(60rem * 0.75)}
html.wide #content .cms-wrap{max-width:none}
#content a{color:var(--accent);text-decoration:none}
#content a:hover{text-decoration:underline}
#content h1{font-size:2rem;letter-spacing:-.025em;margin:var(--space-1) var(--space-0) var(--space-3);color:var(--fg-primary)}
#content h2{letter-spacing:-.02em;color:var(--fg-primary)}
#content .muted{opacity:.62}
#content .small{font-size:.85rem}
#content .row{display:flex;gap:var(--space-2);align-items:center}
#content .grid{display:grid;gap:var(--space-4)}
#content .spacer{flex:1}
/* ===== shared CMS layout helpers (P4 — hoisted from handler inline styles) ===== */
/* page-head row: title + back-link (replaces .row style="justify-content:space-between") */
#content .cms-head{display:flex;justify-content:space-between;align-items:center;gap:var(--space-2)}
/* the head's title sits tight in the flex row (was inline margin:0 on detail/view h1s) */
#content .cms-head h1{margin:0}
/* centred narrow card for sign-in / service-error / not-found pages (one width, was 24/28/32rem) */
#content .cms-card-narrow{max-width:32rem;margin:var(--space-10) auto;text-align:center}
/* footer action-button row (replaces style="margin-top:1.25rem;gap:.6rem"); .center centres it */
#content .cms-actions{display:flex;align-items:center;gap:var(--space-2);margin-top:var(--space-5);flex-wrap:wrap}
#content .cms-actions.center{justify-content:center}
/* read-only detail table: fixed-width label column (replaces <th style="width:8rem">) */
#content .cms-detail th{width:8rem;white-space:nowrap}
#content .who{font-size:.85rem;opacity:.62;margin:var(--space-0) var(--space-1)}
#content .card{background:var(--glass);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--glass-border);border-radius:var(--radius-xl);padding:var(--space-6);box-shadow:var(--shadow-sm)}
#content .navlink{font-size:.9rem;font-weight:600;padding:var(--space-1) var(--space-3);border-radius:var(--radius-lg)}
#content .navlink:hover{background:color-mix(in srgb,var(--accent) 12%,transparent);text-decoration:none}
/* CMS .btn — unified with the widget buttons (.dt-btn/.fm-btn/.md-btn): inline-flex,
   1px transparent border, --radius-lg, subtle deterministic-darken hover (the old
   lift+glow/brightness hover is dropped so every button across the site feels the same). */
#content .btn{display:inline-flex;align-items:center;gap:var(--space-2);background:var(--accent);color:var(--accent-fg);font:inherit;font-size:.9rem;font-weight:600;line-height:1;padding:var(--space-2) var(--space-4);border-radius:var(--radius-lg);border:1px solid transparent;cursor:pointer;white-space:nowrap;text-decoration:none;transition:background .14s ease,border-color .14s ease,color .14s ease,filter .14s ease}
#content .btn:hover{background:color-mix(in srgb,var(--accent) 86%,oklch(0% 0 0));color:var(--accent-fg);text-decoration:none}
#content .btn.ghost{background:transparent;color:var(--fg-primary);border-color:var(--border-muted)}
#content .btn.ghost:hover{background:var(--bg-secondary);color:var(--fg-primary)}
#content .btn.danger{background:var(--danger);border-color:var(--danger)}
#content .btn.danger:hover{background:var(--danger);color:var(--accent-fg);filter:brightness(1.06);text-decoration:none}
#content input,#content textarea,#content select{width:100%;box-sizing:border-box;background:var(--bg-primary);color:inherit;border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--space-3) var(--space-3);font:inherit;font-size:.95rem;transition:border-color .15s ease,box-shadow .15s ease}
#content input:focus,#content textarea:focus,#content select:focus{outline:2px solid var(--accent);border-color:transparent}
/* Native-control polish (Part C): tame the "sad" default <select> — strip the
   platform chrome, add a theme-aware caret, and reserve room for it so long
   options don't collide. Fully-custom open-lists stay out of scope. */
#content select{appearance:none;-webkit-appearance:none;-moz-appearance:none;padding-right:2rem;cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23808a99' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .75rem center}
#content label{display:block;font-size:.8rem;font-weight:600;opacity:.7;margin:var(--space-4) var(--space-0) var(--space-1)}
#content .tag{display:inline-block;font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;padding:var(--space-1) var(--space-2);border-radius:var(--radius-md);background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent)}
#content .tag.draft{background:color-mix(in srgb,var(--warning) 24%,transparent);color:var(--warning)}
#content table{width:100%;border-collapse:collapse}
#content th,#content td{text-align:left;padding:var(--space-3) var(--space-2);border-bottom:1px solid var(--border);font-size:.92rem}
#content th{opacity:.6;font-size:.72rem;text-transform:uppercase;letter-spacing:.04em}
/* DataTable widget (shared handlers/datatable.mix): sortable headers, global
   search, numbered pagination. Co-located here so it composes with the
   #content-scoped table/card/btn rules above and shares their vars. */
#content .visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
#content .datatable-scroll-wrapper{overflow-x:auto}
#content table.datatable{width:100%;border-collapse:collapse}
#content .datatable th.sortable-th{padding:0}
#content .datatable th.sortable-th a{display:inline-flex;align-items:center;gap:var(--space-1);color:inherit;text-decoration:none;padding:var(--space-3) var(--space-2)}
#content .datatable th.sortable-th a:hover{color:var(--accent);text-decoration:none}
#content .datatable th[aria-sort]{opacity:1}
#content .datatable th[aria-sort] a{color:var(--accent);font-weight:700}
#content .datatable .dt-caret{font-size:.8em}
#content .datatable tbody tr{transition:background .12s ease}
#content .datatable tbody tr:hover{background:color-mix(in srgb,var(--accent) 7%,transparent)}
#content .datatable-row-actions{text-align:right;white-space:nowrap}
#content .datatable-results-count{font-weight:400;margin-inline-start:var(--space-2)}
#content .datatable-toolbar{margin:var(--space-4) var(--space-0)}
#content .datatable-toolbar-actions{display:flex;gap:var(--space-2);align-items:center}
#content .datatable-empty-state{margin-top:var(--space-4)}
#content .datatable-pagination-bar{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:var(--space-3);margin-top:var(--space-6)}
#content .datatable-page-list{display:flex;align-items:center;gap:var(--space-2);list-style:none;padding:0;margin:0}
#content .datatable-page-list li{margin:0}
#content .datatable-page-list .btn{padding:var(--space-1) var(--space-3);font-size:.82rem}
#content .page-number-btn{display:inline-flex;min-width:2rem;justify-content:center;padding:var(--space-1) var(--space-2);border-radius:var(--radius-md);text-decoration:none;color:var(--fg-primary);opacity:.7}
#content .page-number-btn:hover{background:var(--bg-secondary);opacity:1;text-decoration:none}
#content .page-number-active{background:var(--accent);color:var(--accent-fg);font-weight:700;opacity:1;pointer-events:none}
#content .dt-ellipsis{padding:var(--space-0) var(--space-1);opacity:.5}
#content .datatable-page-info{margin-inline-start:var(--space-2);opacity:.62}
#content .datatable-pagesize{display:flex;align-items:center;gap:var(--space-2);justify-content:center;flex-wrap:wrap;margin-top:var(--space-3)}
#content .datatable-pagesize a{padding:var(--space-1) var(--space-2);border-radius:var(--radius-md);text-decoration:none;color:var(--fg-primary);opacity:.7}
#content .datatable-pagesize a:hover{background:var(--bg-secondary);opacity:1;text-decoration:none}
#content .dt-pagesize-active{padding:var(--space-1) var(--space-2);border-radius:var(--radius-md);background:var(--accent);color:var(--accent-fg);font-weight:700}
#content .dt-bulk-bar{display:flex;align-items:center;gap:var(--space-3);margin:var(--space-2) var(--space-0)}
#content .dt-bulk-cell{width:var(--space-6);text-align:center}
#content .dt-bulk-cell input{width:auto}
#content .dt-bulk-act[disabled]{opacity:.45;cursor:default;filter:grayscale(.4)}
#content .dt-bulk-bar .dt-bulk-act+.dt-bulk-act{margin-left:var(--space-1)}
#content .dt-bool{font-weight:700}
#content .dt-bool-yes{color:var(--accent)}
#content .dt-bool-no{opacity:.4}
@media (max-width:768px){#content .datatable tbody tr:nth-child(odd){background:color-mix(in srgb,var(--accent) 5%,transparent)}}
#content .flash{background:color-mix(in srgb,var(--accent) 12%,transparent);border:1px solid color-mix(in srgb,var(--accent) 30%,transparent);border-radius:var(--radius-lg);padding:var(--space-3) var(--space-4);margin-bottom:var(--space-4);font-size:.9rem}
#content article.post{font-size:1.05rem}
#content article.post p{margin:var(--space-4) var(--space-0)}
/* Rendered-markdown content (full GFM via the markdown() builtin). base.css
   resets ul/ol list-style, so restore it for prose. */
#content .post ul,#content .post ol{list-style:revert;padding-left:var(--space-6);margin:var(--space-4) var(--space-0)}
#content .post li{margin:var(--space-1) var(--space-0)}
#content .post h1,#content .post h2,#content .post h3,#content .post h4{margin:var(--space-6) var(--space-0) var(--space-3);color:var(--fg-primary)}
#content .post a{color:var(--accent)}
#content .post code{background:color-mix(in srgb,currentColor 8%,transparent);padding:var(--space-1) var(--space-1);border-radius:var(--radius-md);font-size:.9em}
#content .post pre{background:color-mix(in srgb,currentColor 8%,transparent);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--space-3) var(--space-4);overflow:auto}
#content .post pre code{background:none;padding:0}
#content .post blockquote{border-inline-start:3px solid var(--accent);margin:var(--space-4) var(--space-0);padding:var(--space-1) var(--space-4);opacity:.85}
#content .post table{margin:var(--space-4) var(--space-0)}
#content .post img{max-width:100%;border-radius:var(--radius-lg)}
#content .post hr{border:0;border-top:1px solid var(--border);margin:var(--space-6) var(--space-0)}
/* left-sidebar blog nav */
.cms-nav-section{margin:var(--space-0) var(--space-0) var(--space-5)}
.cms-nav-title{font-size:.7rem;text-transform:uppercase;letter-spacing:.08em;opacity:.55;margin:var(--space-0) var(--space-0) var(--space-2)}
.cms-nav-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-1)}
.cms-nav-list a{display:block;padding:var(--space-2) var(--space-2);border-radius:var(--radius-lg);font-size:.92rem;color:inherit;text-decoration:none}
.cms-nav-list a:hover{background:color-mix(in srgb,var(--accent) 14%,transparent)}
.cms-nav-empty{opacity:.5;font-size:.85rem;padding:var(--space-2) var(--space-2)}
.cms-tagline{font-size:.8rem;opacity:.6;line-height:1.4;margin:var(--space-0) var(--space-0) var(--space-4)}
.cms-footer{border-top:1px solid color-mix(in srgb,currentColor 12%,transparent);opacity:.6;font-size:.85rem;padding:var(--space-6);text-align:center}
/* Only the title band ("Message of the Day" / "Appearance") gets the solid
   --bg-tertiary; the very top strip (pin/dots carousel-header) keeps the
   default glass sidebar surface. */
.sidebar .panel-title{background:var(--bg-tertiary)}
/* Bottom-left profile widget + popup (replaces the topnav user links). */
.profile{margin-top:auto;border-block-start:1px solid var(--border);padding:var(--space-2)}
.profile-btn{display:flex;align-items:center;gap:var(--space-2);width:100%;padding:var(--space-2) var(--space-2);border-radius:var(--radius-lg);background:transparent;border:0;color:inherit;cursor:pointer;font:inherit;text-decoration:none}
.profile-btn:hover{background:color-mix(in srgb,var(--accent) 12%,transparent)}
.profile-av{width:1.8rem;height:1.8rem;border-radius:50%;background:var(--accent);color:var(--accent-fg);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.78rem;flex:none}
.profile-name{font-weight:600;font-size:.9rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.profile-pop{display:none;flex-direction:column;gap:var(--space-1);margin:var(--space-1) var(--space-0) var(--space-1);padding:var(--space-1);border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--bg-secondary)}
.profile.open .profile-pop{display:flex}
.profile-pop a{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-lg);font-size:.9rem;color:inherit;text-decoration:none}
.profile-pop a:hover{background:color-mix(in srgb,var(--accent) 14%,transparent)}
.profile-pop a svg{width:1rem;height:1rem;flex:none;opacity:.7}
.profile-pop form{margin:0}
.profile-pop form button{display:flex;align-items:center;gap:var(--space-2);width:100%;padding:var(--space-2) var(--space-3);border-radius:var(--radius-lg);font:inherit;font-size:.9rem;color:inherit;background:none;border:0;cursor:pointer;text-align:left}
.profile-pop form button:hover{background:color-mix(in srgb,var(--accent) 14%,transparent)}
.profile-pop form button svg{width:1rem;height:1rem;flex:none;opacity:.7}
.profile-sep{height:1px;background:var(--border);margin:var(--space-1) var(--space-1)}
.profile-btn svg{width:1rem;height:1rem;flex:none;opacity:.8}
/* CMS nav (LHS Navigation/Posts panels + RHS Posts panel): side padding to
   match the Appearance panel (var(--space-4)); flex links with a leading
   Lucide icon, an ellipsised label, and a trailing lock for private items. */
.cms-nav{padding:var(--space-4)}
.cms-nav-list a{display:flex;align-items:center;gap:var(--space-2);transition:background .12s ease,color .12s ease}
.cms-nav-list a svg{width:1rem;height:1rem;flex:none;opacity:.6}
.cms-nav-list .nav-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cms-nav-list .nav-lock{flex:none;opacity:.55;display:inline-flex;align-items:center}
.cms-nav-list .nav-lock svg{width:.85rem;height:.85rem}
/* Active nav item (set by the boost shim on swap). */
.cms-nav-list a.active{background:color-mix(in srgb,var(--accent) 16%,transparent);color:var(--accent)}

/* Content-swap animation (Part A.4): swapped-in content fades + rises in. The
   first/no-JS full-page load animates via this rule directly; on a boosted
   swap the .cms-wrap element persists (only its innerHTML changes), so the
   boost shim restarts this animation with a reflow nudge. Honours
   reduced-motion. */
#content .cms-wrap{animation:cms-fade-in .28s var(--ease-out,cubic-bezier(.16,1,.3,1))}
/* #dt-region (targeted datatable partial swaps) fades the same way as a full
   content swap — the boost shim restarts it after patching the region. */
#content #dt-region{animation:cms-fade-in .22s var(--ease-out,cubic-bezier(.16,1,.3,1))}
/* Page-load / boosted-swap entrance = FADE ONLY (no translateY). The slide-up belongs to
   scroll-reveal of content sections coming above the fold (the `.reveal`/`fade-in-up` rule
   in site.css, untouched) — it was never meant to fire on a page load / content swap. */
@keyframes cms-fade-in{from{opacity:0}to{opacity:1}}

/* Top loading bar during a boosted nav (Part A.4 shim toggles `.on` + width).
   Fixed, above the chrome; accent-coloured with a soft glow. */
#nav-progress{position:fixed;top:0;left:0;height:2px;width:0;background:linear-gradient(90deg,var(--accent),var(--accent-hover,var(--accent)));box-shadow:0 0 8px var(--accent-glow,transparent);opacity:0;z-index:1000;transition:width .2s ease,opacity .2s ease;pointer-events:none}
#nav-progress.on{opacity:1}

@media (prefers-reduced-motion:reduce){
    #content .cms-wrap,#content #dt-region{animation:none}
    #content .btn{transition:none}
    #nav-progress{transition:opacity .15s ease}
}


/* ===================================================================
   datatable.css
   =================================================================== */
/* datatable.css — the Filament 5 "skin" for the shared SSR datatable widget.
 *
 * Plan of record: _plan/2026-06-15-datatable-filament-parity.md (Phase 1, §4, S-8).
 * Visual target: _doc/datatable/ screenshots (Filament 5 Tables overview).
 *
 * SCOPING — the whole sheet is scoped under `.datatable-skin`, a wrapper class
 * the handler opts INTO (dt_region($html, $id, true) → adds it to #dt-region).
 * A page that does NOT opt in renders byte-identical to before, even though this
 * file is loaded globally: every rule below needs the `.datatable-skin` ancestor
 * to match, so the 5 un-converted live pages are untouched. The `#content`
 * prefix (+ the extra `.datatable-skin` class) gives these rules higher
 * specificity than cms.css's `#content .foo` table/btn/tag rules, so they win;
 * loaded AFTER cms.css, unlayered, so equal-specificity ties also go to us.
 *
 * THEME — the skin now RIDES the shell theme: every --dt-* token is a thin alias
 * onto the global oklch tokens (site.css: --accent / --bg-* / --fg-* /
 * --border-muted / semantic), so the table follows the selected scheme
 * (Ocean/Crimson/…) AND light/dark automatically. No private palette and no
 * light/dark split here — the globals it aliases are already theme-aware. The
 * table is FLAT (.dt-card carries no chrome); .dt-surface is the opt-in themed
 * card for NON-table region content (e.g. the media gallery).
 *
 * CLASS VOCABULARY — this ships the FULL canonical class set now (S-8),
 * including the modal / filter-popover / column-toggle / drag-handle / row-tint
 * classes that Phases 2–5 will emit, so those phases are pure handler work
 * against a ready skin and never re-invent a class name. Phase 1 emits the
 * header / toolbar / table / badge / ring / action / footer / pager subset.
 */

/* ───────────────────────────── tokens ───────────────────────────── */
/* The skin no longer carries its own palette — every --dt-* is a thin ALIAS onto the
   global theme tokens (site.css), so the table follows the selected scheme + light/dark
   automatically. Single block (no light/dark split): the globals it points at are
   already theme-aware. .datatable-skin is the token scope; it rides the persistent
   #dt-region so the skin survives partial swaps.
   NB --dt-border → --border-MUTED (the subtler sibling of --border) for faint row
   separators at table density. */
#content .datatable-skin{
    --dt-accent:       var(--accent);
    --dt-accent-hover: var(--accent-hover);
    --dt-accent-fg:    var(--accent-fg);
    --dt-card:         var(--bg-primary);    /* search input / popover / modal surface */
    --dt-page:         var(--bg-tertiary);
    --dt-strip:        var(--bg-secondary);  /* header / toolbar / thead / bulk-bar strip */
    --dt-row-hover:    var(--row-hover);
    --dt-border:       var(--border-muted);
    --dt-text:         var(--fg-primary);
    --dt-muted:        var(--fg-muted);
    --dt-info:         var(--info);
    --dt-success:      var(--success);
    --dt-warning:      var(--warning);
    --dt-danger:       var(--danger);
    --dt-r-lg:         var(--radius-lg);
    --dt-r-md:         var(--radius-md);
    --dt-r-sm:         var(--radius-sm);
}

/* The datatable is FLAT — no card chrome. dt_render still wraps the table in
   .dt-card, but it carries no bg/border/shadow/radius now, so the table sits flush
   on the #content surface. (Kept the element so a 1-line surface can return later.) */
/* Neutralise ONLY the inner table's .card scroll wrapper (never other .card content
   a handler appends to the region) so the table sits flush. */
#content .datatable-skin .datatable-scroll-wrapper{
    background:none;border:0;border-radius:0;box-shadow:none;
    -webkit-backdrop-filter:none;backdrop-filter:none;padding:0;overflow-x:auto;
}
/* .dt-surface — the opt-in THEMED card for non-table region content (e.g. the media
   gallery) that still wants a container now that .dt-card is flat. Theme-aware via
   the aliased tokens. */
#content .datatable-skin .dt-surface{
    background:var(--dt-card);
    color:var(--dt-text);
    border:1px solid var(--dt-border);
    border-radius:var(--radius-xl);
    overflow:hidden;
    box-shadow:var(--shadow-sm);
}
#content .datatable-skin a{color:var(--dt-accent);text-decoration:none}
#content .datatable-skin a:hover{color:var(--dt-accent-hover);text-decoration:none}
#content .datatable-skin svg{width:1.05em;height:1.05em;vertical-align:-.15em;flex:none}

/* ───────────────────────────── header band ───────────────────────────── */
#content .datatable-skin .dt-header{
    display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-4);
    padding:var(--space-5) var(--space-5);
}
#content .datatable-skin .dt-title{
    font-size:1.4rem;line-height:1.2;font-weight:700;letter-spacing:-.01em;
    color:var(--dt-text);margin:0;
}
/* .dt-count — a forward-declared hook (S-8). Filament's header (the visual
   target) shows NO count chip; the row count lives in the footer range label
   ("Showing X to Y of Z results"). dt_header_band deliberately omits it; a
   handler that wants an inline count can emit <span class="dt-count">. */
#content .datatable-skin .dt-count{
    font-size:.8rem;font-weight:600;color:var(--dt-muted);
    margin-inline-start:var(--space-2);vertical-align:.1em;
}
#content .datatable-skin .dt-subtitle{
    margin:var(--space-1) 0 0;font-size:.9rem;color:var(--dt-muted);
}
#content .datatable-skin .dt-header-actions{display:flex;gap:var(--space-2);align-items:center;flex:none}

/* ── compact header (opts.compact): one dense row — title hard-left, controls right ── */
#content .datatable-skin .dt-header-compact{align-items:center;padding:var(--space-3) var(--space-5);flex-wrap:wrap}
/* the right-aligned control cluster: trash · search · funnel · group · columns · actions */
#content .datatable-skin .dt-header-cluster{
    display:flex;align-items:center;gap:var(--space-2);margin-inline-start:auto;flex-wrap:wrap;justify-content:flex-end;
}
#content .datatable-skin .dt-header-cluster .dt-header-actions{display:contents}
/* the compact search is ~25% narrower than the standalone toolbar search (13rem → ~10rem) */
#content .datatable-skin .dt-search-compact{display:inline-flex}
#content .datatable-skin .dt-search-compact .dt-search-wrap{min-width:10rem}
/* the bulk Delete → a trash icon button; danger-tinted, disabled until rows are selected */
#content .datatable-skin .dt-bulk-trash{position:relative}
#content .datatable-skin .dt-bulk-trash:not([disabled]){color:var(--dt-danger)}
#content .datatable-skin .dt-bulk-trash:not([disabled]):hover{color:var(--dt-danger);border-color:var(--dt-danger);background:color-mix(in srgb,var(--dt-danger) 12%,transparent)}
#content .datatable-skin .dt-bulk-trash[disabled]{opacity:.4;cursor:not-allowed}
#content .datatable-skin .dt-bulk-count-badge{
    position:absolute;top:calc(var(--space-1) * -1);right:calc(var(--space-1) * -1);min-width:1.05rem;height:1.05rem;padding:0 var(--space-1);
    display:inline-flex;align-items:center;justify-content:center;border-radius:var(--radius-full);
    background:var(--dt-danger);color:var(--accent-fg);font-size:.65rem;font-weight:700;line-height:1;
}
/* compact across-pages prompt: a BARE span (no .dt-bulk-bar strip), `hidden` → zero
   footprint idle; when JS unhides it, a thin inline-block bar above the table. */
#content .datatable-skin .dt-sel-all-prompt-compact:not([hidden]){display:inline-block;padding:var(--space-2) var(--space-1)}
@media (max-width:680px){
    #content .datatable-skin .dt-header-compact{flex-direction:row}
    #content .datatable-skin .dt-header-cluster{width:100%;margin-inline-start:0}
}

/* ───────────────────────────── buttons ───────────────────────────── */
#content .datatable-skin .dt-btn{
    display:inline-flex;align-items:center;gap:var(--space-2);
    font:inherit;font-size:.86rem;font-weight:600;line-height:1;
    padding:var(--space-2) var(--space-3);border-radius:var(--radius-lg);
    border:1px solid transparent;cursor:pointer;white-space:nowrap;
    transition:background .14s ease,border-color .14s ease,color .14s ease,filter .14s ease;
}
/* Primary buttons (New entry, filter/group Apply) follow the SELECTED THEME accent
   (--accent / Ocean teal etc.), not the skin's fixed amber. Hover = a Filament-5
   flat DARKER fill derived from --accent (the theme's own --accent-hover goes
   LIGHTER in several schemes, which both inverts the Filament direction and lowers
   contrast against the light --accent-fg, so we darken deterministically instead). */
#content .datatable-skin .dt-btn-primary{background:var(--accent);color:var(--accent-fg);border-color:var(--accent);min-height:var(--ctl-h)}
#content .datatable-skin .dt-btn-primary:hover{background:color-mix(in srgb, var(--accent) 86%, oklch(0% 0 0));color:var(--accent-fg);border-color:color-mix(in srgb, var(--accent) 86%, oklch(0% 0 0))}
#content .datatable-skin .dt-btn-ghost{background:transparent;color:var(--dt-text);border-color:var(--dt-border)}
#content .datatable-skin .dt-btn-ghost:hover{background:var(--dt-strip);color:var(--dt-text)}
#content .datatable-skin .dt-btn-danger{background:var(--dt-danger);color:var(--accent-fg);border-color:var(--dt-danger)}
#content .datatable-skin .dt-btn-danger:hover{filter:brightness(1.06);color:var(--accent-fg)}

/* ───────────────────────────── toolbar band ───────────────────────────── */
/* The widget's search form (class .datatable-toolbar) becomes the toolbar band:
   a strip with the search box + icon buttons (filter funnel / column toggle)
   right-aligned. .dt-toolbar is the skin-emitted wrapper; .datatable-toolbar is
   the historic form class — both styled so either renders correctly. */
#content .datatable-skin .dt-toolbar,
#content .datatable-skin form.datatable-toolbar{
    display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;
    margin:0;padding:var(--space-3) var(--space-5);
    background:var(--dt-strip);border-top:1px solid var(--dt-border);
}
#content .datatable-skin .dt-toolbar-left{display:flex;align-items:center;gap:var(--space-2)}
#content .datatable-skin .dt-toolbar-right{display:flex;align-items:center;gap:var(--space-2);margin-inline-start:auto}

/* search box: a pill with a leading magnifier. Under the skin the widget wraps
   the <input> in .dt-search-wrap; on the historic form the bare input is styled
   to match so a non-wrapped search still looks right. */
#content .datatable-skin .dt-search-wrap{position:relative;display:inline-flex;align-items:center;min-width:13rem}
/* the leading magnifier only (direct child) — NOT the in-input clear × (inside a button) */
#content .datatable-skin .dt-search-wrap>svg{position:absolute;left:var(--space-3);color:var(--dt-muted);pointer-events:none}
#content .datatable-skin .dt-search-wrap input,
#content .datatable-skin form.datatable-toolbar input[type=search],
#content .datatable-skin form.datatable-toolbar input:not([type]){
    width:100%;background:var(--dt-card);color:var(--dt-text);
    border:1px solid var(--dt-border);border-radius:var(--radius-lg);
    padding:var(--space-2) var(--space-3) var(--space-2) var(--space-8);font:inherit;font-size:.88rem;
}
/* live-search clear (×): in-input, right-aligned, shown only when non-empty (JS toggles the
   `hidden` attr). Reserve right padding so text never slides under it. We render our own ×,
   so suppress the browser's native type=search clear button. */
#content .datatable-skin .dt-search-wrap input[data-dt-live]{padding-right:var(--space-8)}
#content .datatable-skin .dt-search-wrap input[data-dt-live][type=search]::-webkit-search-cancel-button{-webkit-appearance:none;display:none}
#content .datatable-skin .dt-search-clear{
    position:absolute;right:var(--space-2);display:inline-flex;align-items:center;justify-content:center;
    width:1.3rem;height:1.3rem;padding:0;border:0;background:transparent;color:var(--dt-muted);
    cursor:pointer;border-radius:var(--radius-full)
}
#content .datatable-skin .dt-search-clear:hover{color:var(--dt-text);background:var(--dt-strip)}
#content .datatable-skin .dt-search-clear svg{position:static;left:auto;width:.8rem;height:.8rem;pointer-events:none}
#content .datatable-skin .dt-search-wrap input:focus,
#content .datatable-skin form.datatable-toolbar input:focus{
    outline:none;border-color:var(--dt-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--dt-accent) 22%,transparent);
}
/* search submit + clear sit quietly next to the box */
#content .datatable-skin form.datatable-toolbar .btn{font-size:.84rem}

/* icon buttons (funnel / column-toggle); count badge on the funnel */
#content .datatable-skin .dt-iconbtn{
    position:relative;display:inline-flex;align-items:center;justify-content:center;
    width:2.1rem;height:2.1rem;border-radius:var(--radius-lg);
    background:transparent;border:1px solid transparent;color:var(--dt-muted);cursor:pointer;
}
#content .datatable-skin .dt-iconbtn:hover{background:var(--dt-card);color:var(--dt-text);border-color:var(--dt-border)}
/* list/card view toggle (media gallery; the future file-manager seed): a pair of
   .dt-iconbtn links where the active view is filled with the theme accent. */
#content .datatable-skin .dt-view-toggle{display:inline-flex;gap:var(--space-1);align-items:center}
#content .datatable-skin .dt-view-toggle .dt-view-active,
#content .datatable-skin .dt-view-toggle .dt-view-active:hover{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}
#content .datatable-skin .dt-badge-count{
    position:absolute;top:calc(var(--space-1) * -1);right:calc(var(--space-1) * -1);min-width:1.05rem;height:1.05rem;
    padding:0 var(--space-1);border-radius:var(--radius-full);background:var(--dt-accent);color:var(--dt-accent-fg);
    font-size:.66rem;font-weight:700;line-height:1.05rem;text-align:center;
}

/* ───────────────────────────── table ───────────────────────────── */
#content .datatable-skin table.datatable{width:100%;border-collapse:collapse;font-size:.9rem}
#content .datatable-skin .datatable thead tr{background:var(--dt-strip)}
#content .datatable-skin .datatable th{
    text-align:left;padding:var(--space-3) var(--space-4);color:var(--dt-muted);
    font-size:.78rem;font-weight:700;text-transform:none;letter-spacing:0;
    border-top:1px solid var(--dt-border);border-bottom:1px solid var(--dt-border);
    white-space:nowrap;opacity:1;
}
#content .datatable-skin .datatable th.sortable-th{padding:0}
#content .datatable-skin .datatable th.sortable-th a{
    display:inline-flex;align-items:center;gap:var(--space-1);color:var(--dt-muted);
    padding:var(--space-3) var(--space-4);font-weight:700;
}
#content .datatable-skin .datatable th.sortable-th a:hover{color:var(--dt-text)}
#content .datatable-skin .datatable th[aria-sort] a{color:var(--dt-text)}
#content .datatable-skin .datatable .dt-caret{color:var(--dt-accent);font-size:.9em}
#content .datatable-skin .datatable td{
    padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--dt-border);color:var(--dt-text);vertical-align:middle;
}
#content .datatable-skin .datatable tbody tr{transition:background .12s ease}
#content .datatable-skin .datatable tbody tr:hover{background:var(--dt-row-hover)}
#content .datatable-skin .datatable tbody tr:last-child td{border-bottom:0}
#content .datatable-skin .datatable td .muted,
#content .datatable-skin .datatable .dt-desc{color:var(--dt-muted)}
#content .datatable-skin .datatable .dt-desc{display:block;font-size:.8rem;margin-top:var(--space-1)}
#content .datatable-skin .datatable td strong{font-weight:600;color:var(--dt-text)}
/* alignment helpers — forward-declared hooks (S-8) for a future `align` col opt
   (deferred; the screenshots are all left-aligned). Emit on <td>/<th> when it lands. */
#content .datatable-skin .dt-cell-center{text-align:center}
#content .datatable-skin .dt-cell-right{text-align:right}

/* selection checkbox column */
#content .datatable-skin .dt-bulk-cell{width:1.5rem;text-align:center}
#content .datatable-skin .dt-bulk-cell input{width:auto;accent-color:var(--dt-accent)}

/* ───────────────────────────── badge pills ───────────────────────────── */
#content .datatable-skin .dt-badge{
    display:inline-flex;align-items:center;gap:var(--space-1);
    padding:var(--space-1) var(--space-2);border-radius:var(--radius-full);
    font-size:.74rem;font-weight:600;line-height:1.4;white-space:nowrap;
    border:1px solid transparent;
}
#content .datatable-skin .dt-badge svg{width:.85em;height:.85em}
#content .datatable-skin .dt-badge-primary{background:color-mix(in srgb,var(--dt-accent) 18%,transparent);color:var(--dt-accent);border-color:color-mix(in srgb,var(--dt-accent) 35%,transparent)}
#content .datatable-skin .dt-badge-success{background:color-mix(in srgb,var(--dt-success) 16%,transparent);color:var(--dt-success);border-color:color-mix(in srgb,var(--dt-success) 32%,transparent)}
#content .datatable-skin .dt-badge-warning{background:color-mix(in srgb,var(--dt-warning) 18%,transparent);color:var(--dt-warning);border-color:color-mix(in srgb,var(--dt-warning) 34%,transparent)}
#content .datatable-skin .dt-badge-danger{background:color-mix(in srgb,var(--dt-danger) 16%,transparent);color:var(--dt-danger);border-color:color-mix(in srgb,var(--dt-danger) 32%,transparent)}
#content .datatable-skin .dt-badge-info{background:color-mix(in srgb,var(--dt-info) 16%,transparent);color:var(--dt-info);border-color:color-mix(in srgb,var(--dt-info) 32%,transparent)}
#content .datatable-skin .dt-badge-gray{background:color-mix(in srgb,var(--dt-muted) 16%,transparent);color:var(--dt-muted);border-color:color-mix(in srgb,var(--dt-muted) 30%,transparent)}

/* ───────────────────────────── ring + boolean icons ───────────────────────────── */
#content .datatable-skin .dt-icon-ring{
    display:inline-flex;align-items:center;justify-content:center;
    width:1.5rem;height:1.5rem;border-radius:var(--radius-full);border:1.5px solid currentColor;
}
#content .datatable-skin .dt-icon-ring svg{width:.95em;height:.95em}
#content .datatable-skin .dt-ring-yes{color:var(--dt-success)}
#content .datatable-skin .dt-ring-no{color:var(--dt-danger)}
/* the historic ✓/✗ glyph cell, re-tinted under the skin */
#content .datatable-skin .dt-bool-yes{color:var(--dt-success)}
#content .datatable-skin .dt-bool-no{color:var(--dt-danger);opacity:1}

/* ───────────────────────────── row actions ───────────────────────────── */
#content .datatable-skin .datatable-row-actions{text-align:right;white-space:nowrap}
#content .datatable-skin .dt-action,
#content .datatable-skin .datatable-row-actions a{
    display:inline-flex;align-items:center;gap:var(--space-1);
    font-size:1rem;font-weight:600;color:var(--dt-accent);
    border-radius:var(--dt-r-sm);
}
#content .datatable-skin .dt-action:hover,
#content .datatable-skin .datatable-row-actions a:hover{background:color-mix(in srgb,var(--dt-accent) 12%,transparent);color:var(--dt-accent-hover)}
#content .datatable-skin .dt-action-danger{color:var(--dt-danger)}
#content .datatable-skin .dt-action-danger:hover{background:color-mix(in srgb,var(--dt-danger) 12%,transparent);color:var(--dt-danger)}
#content .datatable-skin .datatable-row-actions a+a,
#content .datatable-skin .dt-action+.dt-action{margin-inline-start:var(--space-1)}

/* ───────────────────────────── bulk bar ───────────────────────────── */
#content .datatable-skin .dt-bulk-bar{
    display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;
    padding:var(--space-3) var(--space-5);background:var(--dt-strip);border-top:1px solid var(--dt-border);
}
#content .datatable-skin .dt-bulk-bar .btn{
    display:inline-flex;align-items:center;gap:var(--space-1);
    background:transparent;border:1px solid var(--dt-border);color:var(--dt-text);
    font-size:.82rem;font-weight:600;padding:var(--space-2) var(--space-3);border-radius:var(--radius-lg);
}
#content .datatable-skin .dt-bulk-bar .btn.danger{color:var(--dt-danger);border-color:color-mix(in srgb,var(--dt-danger) 40%,transparent)}
#content .datatable-skin .dt-bulk-bar .btn.danger:hover{background:color-mix(in srgb,var(--dt-danger) 12%,transparent)}
#content .datatable-skin .dt-bulk-act[disabled]{opacity:.45;cursor:default;filter:grayscale(.4)}
/* select-all-across-pages prompt (Phase 3, S-5) */
#content .datatable-skin .dt-sel-all-prompt{color:var(--dt-muted)}
#content .datatable-skin .dt-sel-all-link{background:none;border:0;padding:0;color:var(--dt-accent);font-weight:600;font-size:inherit;cursor:pointer;text-decoration:underline}
#content .datatable-skin .dt-sel-all-link:hover{color:var(--dt-accent-hover)}
#content .datatable-skin .dt-bulk-count{color:var(--dt-muted);font-size:.82rem}

/* ───────────────────────────── row tints (row_class → dt-row-*) ───────────────────────────── */
#content .datatable-skin .datatable tr.dt-row-green td{box-shadow:inset 3px 0 0 var(--dt-success);background:color-mix(in srgb,var(--dt-success) 7%,transparent)}
#content .datatable-skin .datatable tr.dt-row-amber td{box-shadow:inset 3px 0 0 var(--dt-warning);background:color-mix(in srgb,var(--dt-warning) 7%,transparent)}
#content .datatable-skin .datatable tr.dt-row-red td{box-shadow:inset 3px 0 0 var(--dt-danger);background:color-mix(in srgb,var(--dt-danger) 7%,transparent)}

/* ───────────────────────────── footer (range / per-page / pager) ───────────────────────────── */
#content .datatable-skin .dt-footer{
    display:flex;align-items:center;gap:var(--space-4);flex-wrap:wrap;
    padding:var(--space-3) var(--space-5);border-top:1px solid var(--dt-border);
}
#content .datatable-skin .dt-results-range{color:var(--dt-muted);font-size:.82rem;margin-inline-end:auto}
#content .datatable-skin .dt-perpage{display:flex;align-items:center;gap:var(--space-2);margin:0}
#content .datatable-skin .dt-perpage-label{color:var(--dt-muted);font-size:.82rem;font-weight:500;margin:0}
#content .datatable-skin .dt-perpage-select{
    width:auto;background:var(--dt-strip);color:var(--dt-text);
    border:1px solid var(--dt-border);border-radius:var(--radius-lg);
    padding:var(--space-1) var(--space-8) var(--space-1) var(--space-3);font:inherit;font-size:.82rem;cursor:pointer;
}
#content .datatable-skin .dt-perpage-go{
    background:var(--dt-strip);color:var(--dt-text);border:1px solid var(--dt-border);
    border-radius:var(--radius-lg);padding:var(--space-1) var(--space-3);font:inherit;font-size:.8rem;cursor:pointer;
}

/* pager: numbered amber boxes + chevron prev/next + « » extreme links */
#content .datatable-skin .datatable-pagination-bar{
    display:flex;align-items:center;gap:var(--space-1);margin:0;padding:0;justify-content:flex-end;
}
#content .datatable-skin .datatable-page-list{display:flex;align-items:center;gap:var(--space-1);list-style:none;padding:0;margin:0}
#content .datatable-skin .datatable-page-list .btn,
#content .datatable-skin .page-number-btn,
#content .datatable-skin .dt-page-extreme{
    display:inline-flex;align-items:center;justify-content:center;
    min-width:2.1rem;height:2.1rem;padding:0 var(--space-2);
    background:var(--dt-strip);border:1px solid var(--dt-border);border-radius:var(--radius-lg);
    color:var(--dt-text);font-size:.84rem;font-weight:600;opacity:1;
}
#content .datatable-skin .datatable-page-list .btn:hover,
#content .datatable-skin .page-number-btn:hover,
#content .datatable-skin .dt-page-extreme:hover{background:var(--dt-card);border-color:var(--dt-accent);color:var(--dt-text)}
#content .datatable-skin .page-number-active{
    background:var(--dt-accent);border-color:var(--dt-accent);color:var(--dt-accent-fg);
    pointer-events:none;font-weight:700;
}
#content .datatable-skin .dt-ellipsis{padding:0 var(--space-1);color:var(--dt-muted);align-self:center}
#content .datatable-skin .datatable-page-info{display:none}  /* "Page N of M" → the range label carries the count under the skin */

/* historic standalone pager/size-selector, kept usable if a skin page still
   emits them (e.g. partial paths): re-tint so they never show shell-blue */
#content .datatable-skin .datatable-pagesize a{color:var(--dt-text)}
#content .datatable-skin .dt-pagesize-active{background:var(--dt-accent);color:var(--dt-accent-fg)}

/* ───────────────────────────── empty state ───────────────────────────── */
#content .datatable-skin .datatable-empty-state{
    margin:0;padding:var(--space-10) var(--space-5);text-align:center;background:none;border:0;border-radius:0;
}
#content .datatable-skin .datatable-empty-state p{color:var(--dt-muted)}

/* ═══════════════════════ Phase 2–5 classes (shipped now, S-8) ═══════════════════════ */

/* filter funnel popover — native <details>; inline JS adds click-away/float (Phase 2) */
#content .datatable-skin .dt-filter-pop,#content .datatable-skin .dt-groupby-pop{position:relative;display:inline-block}
#content .datatable-skin .dt-filter-pop>summary,#content .datatable-skin .dt-groupby-pop>summary{list-style:none;cursor:pointer}
#content .datatable-skin .dt-filter-pop>summary::-webkit-details-marker,#content .datatable-skin .dt-groupby-pop>summary::-webkit-details-marker{display:none}
#content .datatable-skin .dt-filter-panel,#content .datatable-skin .dt-groupby-panel{
    position:absolute;right:0;top:calc(100% + var(--space-2));z-index:50;min-width:16rem;
    background:var(--dt-card);border:1px solid var(--dt-border);border-radius:var(--radius-xl);
    box-shadow:var(--shadow-popover);padding:var(--space-4);
}
#content .datatable-skin .dt-filter-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--space-3)}
#content .datatable-skin .dt-filter-head strong{font-size:.92rem;color:var(--dt-text)}
#content .datatable-skin .dt-filter-reset{color:var(--dt-danger);font-size:.82rem;font-weight:600}
#content .datatable-skin .dt-filter-field{margin:var(--space-3) 0}
#content .datatable-skin .dt-filter-field label{display:block;font-size:.8rem;color:var(--dt-muted);margin-bottom:var(--space-1);font-weight:600}
#content .datatable-skin .dt-filter-apply{margin-top:var(--space-2)}
#content .datatable-skin .dt-filter-chip{
    display:inline-flex;align-items:center;gap:var(--space-1);
    background:color-mix(in srgb,var(--dt-accent) 14%,transparent);color:var(--dt-accent);
    border:1px solid color-mix(in srgb,var(--dt-accent) 30%,transparent);
    border-radius:var(--radius-full);padding:var(--space-1) var(--space-2);font-size:.76rem;font-weight:600;
}
#content .datatable-skin .dt-filter-chip:hover{background:color-mix(in srgb,var(--dt-accent) 22%,transparent)}
/* the search form is a flex row so it lays out beside the funnel in the wrapper */
#content .datatable-skin .dt-search-form{display:flex;align-items:center;gap:var(--space-3);margin:0}
/* active-filter chips strip (below the toolbar) */
#content .datatable-skin .dt-filter-chips{
    display:flex;flex-wrap:wrap;gap:var(--space-2);align-items:center;
    padding:var(--space-3) var(--space-5);background:var(--dt-strip);border-top:1px solid var(--dt-border);
}
/* the funnel panel's controls */
#content .datatable-skin .dt-filter-field select,
#content .datatable-skin .dt-filter-field input{
    width:100%;padding:var(--space-2) var(--space-2);border-radius:var(--radius-lg);
    background:var(--dt-page);border:1px solid var(--dt-border);color:var(--dt-text);font-size:.85rem;
}
#content .datatable-skin .dt-filter-field select:focus,
#content .datatable-skin .dt-filter-field input:focus{outline:2px solid var(--dt-accent);outline-offset:-1px}
/* multiple-select filter: a checkbox group (JS joins to one comma value on submit) */
#content .datatable-skin .dt-filter-checks{display:flex;flex-direction:column;gap:var(--space-1);margin-top:var(--space-1)}
#content .datatable-skin .dt-check{display:flex;align-items:center;gap:var(--space-2);font-size:.85rem;color:var(--dt-text);font-weight:500;cursor:pointer}
/* reset the generic .dt-filter-field input styling for the checkboxes */
#content .datatable-skin .dt-check input{width:auto;flex:0 0 auto;padding:0;border:0;background:none;accent-color:var(--dt-accent)}
/* daterange: two native date inputs */
#content .datatable-skin .dt-daterange{display:flex;align-items:center;gap:var(--space-2)}
#content .datatable-skin .dt-daterange input{flex:1;min-width:0}
#content .datatable-skin .dt-daterange-sep{color:var(--dt-muted);flex:0 0 auto}

/* column-visibility toggle popover (Phase 2) */
#content .datatable-skin .dt-col-toggle{position:relative;display:inline-block}
#content .datatable-skin .dt-col-toggle>summary{list-style:none;cursor:pointer}
#content .datatable-skin .dt-col-toggle>summary::-webkit-details-marker{display:none}
#content .datatable-skin .dt-col-panel{
    position:absolute;right:0;top:calc(100% + var(--space-2));z-index:50;min-width:12rem;
    background:var(--dt-card);border:1px solid var(--dt-border);border-radius:var(--radius-xl);
    box-shadow:var(--shadow-popover);padding:var(--space-3);
}
#content .datatable-skin .dt-col-panel label{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-2);font-size:.85rem;color:var(--dt-text);border-radius:var(--dt-r-sm)}
#content .datatable-skin .dt-col-panel label:hover{background:var(--dt-strip)}
/* row-action "⋮" dropdown (Phase 3) — a <details> menu of action links/buttons */
#content .datatable-skin .dt-row-menu{position:relative;display:inline-block}
#content .datatable-skin .dt-row-menu>summary{list-style:none;cursor:pointer}
#content .datatable-skin .dt-row-menu>summary::-webkit-details-marker{display:none}
#content .datatable-skin .dt-row-menu-panel{
    position:absolute;right:0;top:calc(100% + var(--space-1));z-index:40;min-width:9rem;
    background:var(--dt-card);border:1px solid var(--dt-border);border-radius:var(--radius-xl);
    box-shadow:var(--shadow-popover);padding:var(--space-1);display:flex;flex-direction:column;gap:1px;
}
/* Dropdown ⋮-menu rows reuse .dt-action but need a comfortable tap target — the
   inline-row padding removal must NOT leak here, so restore vertical padding. */
#content .datatable-skin .dt-row-menu-panel>.dt-action,
#content .datatable-skin .dt-row-menu-panel>.dt-btn{justify-content:flex-start;width:100%;padding:var(--space-2) var(--space-2)}
/* column manager rows are toggle LINKS (Lane A, no-JS-correct) */
#content .datatable-skin .dt-col-item{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-2);font-size:.85rem;color:var(--dt-muted);border-radius:var(--dt-r-sm);text-decoration:none;white-space:nowrap}
#content .datatable-skin .dt-col-item:hover{background:var(--dt-strip)}
#content .datatable-skin .dt-col-item.dt-col-on{color:var(--dt-text)}
#content .datatable-skin .dt-col-item svg{color:var(--dt-accent)}
#content .datatable-skin .dt-col-item .dt-col-box{width:1em;height:1em;border:1px solid var(--dt-border);border-radius:var(--dt-r-sm);flex:none}

/* native <dialog> confirm modal (Phase 3) — S-6 canonical: .dt-modal + ::backdrop */
#content .datatable-skin .dt-modal,
.datatable-skin .dt-modal{
    border:1px solid var(--dt-border,rgba(255,255,255,.08));border-radius:var(--radius-xl);
    background:var(--dt-card,#0f172a);color:var(--dt-text,#f8fafc);
    padding:var(--space-6);max-width:24rem;width:calc(100% - var(--space-8));
    box-shadow:var(--shadow-modal);
}
.datatable-skin .dt-modal::backdrop{background:var(--overlay)}
.datatable-skin .dt-modal-icon{
    display:flex;align-items:center;justify-content:center;width:3rem;height:3rem;margin:0 auto var(--space-3);
    border-radius:var(--radius-full);background:color-mix(in srgb,var(--dt-danger,#f43f5e) 18%,transparent);color:var(--dt-danger,#f43f5e);
}
.datatable-skin .dt-modal-title{text-align:center;font-size:1.05rem;font-weight:700;margin:0 0 var(--space-1)}
.datatable-skin .dt-modal-body{text-align:center;color:var(--dt-muted,#94a3b8);font-size:.9rem;margin:0 0 var(--space-4)}
.datatable-skin .dt-modal-actions{display:flex;gap:var(--space-3);justify-content:center}

/* column alignment (deferred Phase-1 `align` opt) — works skin or unskinned */
#content .datatable .dt-align-left{text-align:left}
#content .datatable .dt-align-center{text-align:center}
#content .datatable .dt-align-right{text-align:right}

/* grouping (Phase 4b) — flat spanning group-header rows + the Group-by select */
#content .datatable-skin .datatable tr.dt-group-header td{
    background:var(--dt-strip);font-weight:600;color:var(--dt-text);
    padding:var(--space-2) var(--space-4);border-top:1px solid var(--dt-border)
}
#content .datatable-skin .dt-group-label{
    color:var(--dt-muted);font-weight:500;text-transform:uppercase;
    font-size:.72rem;letter-spacing:.04em;margin-inline-end:var(--space-2)
}
#content .datatable-skin .dt-groupby{display:inline-flex;align-items:center;gap:var(--space-2)}

/* summary footer (Phase 4a) — <tfoot> aggregate row over the filtered dataset */
#content .datatable-skin .datatable tfoot tr.dt-summary-row{background:var(--dt-strip);border-top:2px solid var(--dt-border)}
#content .datatable-skin .datatable tfoot .dt-summary-cell{padding:var(--space-3) var(--space-4);font-weight:600;color:var(--dt-text);font-variant-numeric:tabular-nums;white-space:nowrap}

/* drag-reorder handle (the handle class is reserved; Phase 5 ships move-links below) */
#content .datatable-skin .dt-drag-handle{color:var(--dt-muted);cursor:grab;display:inline-flex;align-items:center}
#content .datatable-skin .dt-drag-handle:active{cursor:grabbing}

/* reorder move-links (Phase 5) — ▲/▼ submit buttons in a narrow leading column */
#content .datatable-skin .dt-reorder-cell{width:1%;white-space:nowrap;text-align:center}
#content .datatable-skin .dt-reorder{display:inline-flex;flex-direction:column;gap:1px;line-height:1}
#content .datatable-skin .dt-move-btn{
    appearance:none;border:1px solid var(--dt-border);background:transparent;color:var(--dt-muted);
    cursor:pointer;font-size:.6rem;line-height:1;padding:var(--space-1) var(--space-2);border-radius:var(--dt-r-sm)
}
#content .datatable-skin .dt-move-btn:hover{color:var(--dt-accent);border-color:var(--dt-accent)}

/* ───────────────────────────── responsive + motion ───────────────────────────── */
@media (max-width:680px){
    #content .datatable-skin .dt-header{flex-direction:column;gap:var(--space-3)}
    #content .datatable-skin .dt-footer{justify-content:center}
    #content .datatable-skin .dt-results-range{margin-inline-end:0;width:100%;text-align:center}
}
@media (prefers-reduced-motion:reduce){
    #content .datatable-skin .dt-btn,
    #content .datatable-skin .datatable tbody tr{transition:none}
}


/* ===================================================================
   forms.css
   =================================================================== */
/* forms.css — the Filament 5 "skin" for the shared SSR forms widget (forms.mix).
 *
 * Plan of record: _plan/2026-06-17-forms-widget.md (§5).
 * Visual target: _doc/forms/ screenshots (Filament 5 Forms — ANATOMY only, never
 * its palette: Filament's orange/blue accent is replaced everywhere by the global
 * --accent ocean-blue).
 *
 * SCOPING — the whole sheet is scoped under `.forms-skin`, a wrapper class fm_open
 * adds to the <form> when opts.skin == true. A form that does NOT opt in renders
 * through the existing cms.css #content styling (no .forms-skin match here), so the
 * un-converted forms are untouched even though this file loads globally. The
 * `#content` prefix + the extra `.forms-skin` class give these rules higher
 * specificity than cms.css's `#content input/label/.btn` rules, so they win; loaded
 * AFTER cms.css, unlayered, so equal-specificity ties also go to us.
 *
 * THEME — like datatable.css, the skin RIDES the shell theme: every --fm-* token is
 * a thin alias onto the global oklch tokens (site.css: --accent / --bg-* / --fg-* /
 * --border / --border-muted / semantic). One block, NO light/dark split — the
 * globals it aliases are already theme-aware (html.light/html.dark + scheme-*).
 *
 * CLASS VOCABULARY — ships the full canonical set now; the affix-button (password
 * eye-toggle), color-swatch, and segment (toggle-buttons) classes are forward-
 * declared hooks for later phases so those phases are pure handler/JS work.
 */

/* ───────────────────────────── tokens ───────────────────────────── */
#content .forms-skin{
    --fm-accent:        var(--accent);
    --fm-accent-hover:  var(--accent-hover);
    --fm-accent-fg:     var(--accent-fg);
    --fm-card:          var(--bg-primary);    /* control + section surface */
    --fm-page:          var(--bg-tertiary);
    --fm-strip:         var(--bg-secondary);  /* affix face / section header tint */
    --fm-border:        var(--border-muted);
    --fm-border-strong: var(--border);
    --fm-text:          var(--fg-primary);
    --fm-muted:         var(--fg-muted);
    --fm-info:          var(--info);
    --fm-success:       var(--success);
    --fm-warning:       var(--warning);
    --fm-danger:        var(--danger);
    --fm-r-lg:          var(--radius-lg);
    --fm-r-md:          var(--radius-md);
    --fm-r-sm:          var(--radius-sm);
}

#content .forms-skin.fm-form{margin:0}
#content .forms-skin svg{width:1.05em;height:1.05em;vertical-align:-.15em;flex:none}

/* ───────────────────────────── section card ───────────────────────────── */
#content .forms-skin .fm-section{
    background:var(--fm-card);
    color:var(--fm-text);
    border:1px solid var(--fm-border);
    border-radius:var(--radius-xl);
    overflow:hidden;
    box-shadow:var(--shadow-sm);
    margin:0 0 var(--space-5);
}
#content .forms-skin .fm-section-head{
    display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-4);
    padding:var(--space-4) var(--space-5);border-bottom:1px solid var(--fm-border);
}
#content .forms-skin .fm-section-title{
    font-size:1.05rem;line-height:1.25;font-weight:700;letter-spacing:-.01em;
    color:var(--fm-text);margin:0;
}
#content .forms-skin .fm-section-sub{margin:var(--space-1) 0 0;font-size:.85rem;color:var(--fm-muted)}
/* forward-declared collapse chevron hook (Phase 2+) */
#content .forms-skin .fm-section-chevron{color:var(--fm-muted);flex:none}
#content .forms-skin .fm-section-body{padding:var(--space-5)}

/* ───────────────────────────── field grid ───────────────────────────── */
#content .forms-skin .fm-grid{display:grid;gap:var(--space-4) var(--space-5);align-items:start}
#content .forms-skin .fm-cols-1{grid-template-columns:minmax(0,1fr)}
#content .forms-skin .fm-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}
#content .forms-skin .fm-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}
#content .forms-skin .fm-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}
#content .forms-skin .fm-span-2{grid-column:1 / -1}
/* collapse to one column on narrow viewports (placed AFTER the cols rules so it
   wins the equal-specificity tie when active; inactive at wide widths) */
@media (max-width:640px){
    #content .forms-skin .fm-grid{grid-template-columns:minmax(0,1fr)}
}

/* ───────────────────────────── field ───────────────────────────── */
#content .forms-skin .fm-field{display:flex;flex-direction:column;gap:var(--space-2);min-width:0}
#content .forms-skin .fm-label{
    display:block;margin:0;font-size:.82rem;font-weight:600;line-height:1.3;
    color:var(--fm-text);opacity:1;
}
#content .forms-skin .fm-req{color:var(--fm-danger);font-weight:700;margin-inline-start:var(--space-1)}
#content .forms-skin .fm-help{margin:0;font-size:.8rem;line-height:1.4;color:var(--fm-muted)}
#content .forms-skin .fm-error{margin:0;font-size:.8rem;line-height:1.4;color:var(--fm-danger);font-weight:500}
#content .forms-skin .fm-note{
    grid-column:1 / -1;margin:var(--space-1) 0 0;font-size:.8rem;line-height:1.5;color:var(--fm-muted);
}

/* ───────────────────────────── controls ───────────────────────────── */
/* background-COLOR (not the shorthand) so the select caret background-image survives. */
#content .forms-skin .fm-control{
    width:100%;box-sizing:border-box;
    background-color:var(--fm-card);color:var(--fm-text);
    border:1px solid var(--fm-border);border-radius:var(--radius-lg);
    padding:var(--space-2) var(--space-3);font:inherit;font-size:.9rem;line-height:1.4;
    transition:border-color .14s ease,box-shadow .14s ease;
}
#content .forms-skin .fm-control:hover{border-color:var(--fm-border-strong)}
#content .forms-skin .fm-control:focus{
    outline:none;border-color:var(--fm-accent);
    box-shadow:0 0 0 3px color-mix(in srgb,var(--fm-accent) 22%,transparent);
}
#content .forms-skin .fm-control::placeholder{color:var(--fm-muted)}
#content .forms-skin .fm-control:disabled{opacity:.55;cursor:not-allowed}
#content .forms-skin textarea.fm-control{min-height:var(--space-20);resize:vertical}
#content .forms-skin textarea.fm-control.fm-mono{font-family:var(--font-mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace)}
/* native <select> caret (re-add under the skin; theme-aware stroke) */
#content .forms-skin select.fm-control{
    appearance:none;-webkit-appearance:none;-moz-appearance:none;
    padding-right:var(--space-10);cursor:pointer;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23808a99' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat:no-repeat;background-position:right var(--space-3) center;
}

/* error state */
#content .forms-skin .fm-field.is-error .fm-control{border-color:var(--fm-danger)}
#content .forms-skin .fm-field.is-error .fm-control:focus{
    box-shadow:0 0 0 3px color-mix(in srgb,var(--fm-danger) 22%,transparent);
}
#content .forms-skin .fm-field.is-error .fm-affix{border-color:var(--fm-danger)}

/* ───────────────────────────── affixes ───────────────────────────── */
/* prefix/suffix fused inside one border; the control goes border-less, the wrapper
   carries the border + focus-within ring (the Filament fused-affix look). */
#content .forms-skin .fm-affix{
    display:flex;align-items:stretch;
    background-color:var(--fm-card);
    border:1px solid var(--fm-border);border-radius:var(--radius-lg);overflow:hidden;
    transition:border-color .14s ease,box-shadow .14s ease;
}
#content .forms-skin .fm-affix:focus-within{
    border-color:var(--fm-accent);
    box-shadow:0 0 0 3px color-mix(in srgb,var(--fm-accent) 22%,transparent);
}
#content .forms-skin .fm-affix .fm-control{
    border:0;border-radius:0;background-color:transparent;flex:1;min-width:0;
}
#content .forms-skin .fm-affix .fm-control:focus{box-shadow:none}
#content .forms-skin .fm-affix-text{
    display:flex;align-items:center;padding:0 var(--space-3);
    background-color:var(--fm-strip);color:var(--fm-muted);
    font-size:.85rem;white-space:nowrap;
}
/* forward-declared affix button (password eye-toggle / color swatch — Phase 2/4) */
#content .forms-skin .fm-affix-btn{
    display:inline-flex;align-items:center;justify-content:center;
    padding:0 var(--space-3);border:0;background:var(--fm-strip);color:var(--fm-muted);
    cursor:pointer;border-inline-start:1px solid var(--fm-border);
}
#content .forms-skin .fm-affix-btn:hover{color:var(--fm-text)}
#content .forms-skin .fm-color-swatch{
    width:1.4rem;height:1.4rem;border-radius:var(--radius-full);align-self:center;
    margin-inline-end:var(--space-2);border:1px solid var(--fm-border);flex:none;
}

/* ───────────────────────────── checkbox / radio ───────────────────────────── */
#content .forms-skin .fm-check{
    display:flex;align-items:flex-start;gap:var(--space-2);cursor:pointer;
    font-weight:400;margin:0;opacity:1;
}
#content .forms-skin .fm-check-input{
    width:1.15rem;height:1.15rem;margin:.1rem 0 0;flex:none;cursor:pointer;
    accent-color:var(--fm-accent);
}
#content .forms-skin .fm-check-body{display:flex;flex-direction:column;gap:var(--space-1);min-width:0}
#content .forms-skin .fm-check-label{font-size:.9rem;font-weight:600;line-height:1.3;color:var(--fm-text)}
#content .forms-skin .fm-check-desc{font-size:.8rem;line-height:1.4;color:var(--fm-muted)}
#content .forms-skin .fm-radio-group{display:flex;flex-direction:column;gap:var(--space-2)}
#content .forms-skin .fm-radio-item{align-items:center}

/* toggle = a pill switch (hide native, render track + thumb; accent track when on) */
#content .forms-skin .fm-toggle .fm-check-input{
    appearance:none;-webkit-appearance:none;-moz-appearance:none;
    width:2.5rem;height:1.4rem;border-radius:var(--radius-full);flex:none;
    background:var(--fm-border-strong);border:0;cursor:pointer;position:relative;
    margin-top:.05rem;transition:background .15s ease;
}
#content .forms-skin .fm-toggle .fm-check-input::after{
    content:"";position:absolute;top:.15rem;left:.15rem;
    width:1.1rem;height:1.1rem;border-radius:var(--radius-full);background:var(--accent-fg);
    box-shadow:var(--shadow-sm);transition:transform .15s ease;
}
#content .forms-skin .fm-toggle .fm-check-input:checked{background:var(--fm-accent)}
#content .forms-skin .fm-toggle .fm-check-input:checked::after{transform:translateX(1.1rem)}

/* forward-declared segmented toggle-buttons (Phase 4) */
#content .forms-skin .fm-segment{display:inline-flex;border:1px solid var(--fm-border);border-radius:var(--radius-md);overflow:hidden}
#content .forms-skin .fm-segment-item{
    display:inline-flex;align-items:center;gap:var(--space-1);padding:var(--space-2) var(--space-3);
    background:var(--fm-card);color:var(--fm-text);cursor:pointer;font-size:.86rem;font-weight:600;
    border-inline-start:1px solid var(--fm-border);
}
#content .forms-skin .fm-segment-item:first-child{border-inline-start:0}
#content .forms-skin .fm-segment-item.is-active{background:var(--fm-accent);color:var(--fm-accent-fg)}

/* ───────────────────────────── actions ───────────────────────────── */
#content .forms-skin .fm-actions{
    display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;
    margin-top:var(--space-6);
}
#content .forms-skin .fm-actions-meta{margin-inline-start:auto;color:var(--fm-muted);font-size:.85rem}

/* ───────────────────────────── buttons ───────────────────────────── */
#content .forms-skin .fm-btn{
    display:inline-flex;align-items:center;gap:var(--space-2);
    font:inherit;font-size:.9rem;font-weight:600;line-height:1;
    padding:var(--space-2) var(--space-4);border-radius:var(--radius-lg);
    border:1px solid transparent;cursor:pointer;white-space:nowrap;text-decoration:none;
    transition:background .14s ease,border-color .14s ease,color .14s ease,filter .14s ease;
}
/* primary follows the SELECTED THEME accent; hover = a deterministic darker fill
   (the theme's --accent-hover goes LIGHTER in some schemes — same trick as datatable). */
#content .forms-skin .fm-btn-primary{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}
#content .forms-skin .fm-btn-primary:hover{background:color-mix(in srgb,var(--accent) 86%,oklch(0% 0 0));color:var(--accent-fg);border-color:color-mix(in srgb,var(--accent) 86%,oklch(0% 0 0));text-decoration:none}
#content .forms-skin .fm-btn-ghost{background:transparent;color:var(--fm-text);border-color:var(--fm-border)}
#content .forms-skin .fm-btn-ghost:hover{background:var(--fm-strip);color:var(--fm-text);text-decoration:none}
#content .forms-skin .fm-btn-danger{background:var(--fm-danger);color:var(--accent-fg);border-color:var(--fm-danger)}
#content .forms-skin .fm-btn-danger:hover{filter:brightness(1.06);color:var(--accent-fg);text-decoration:none}
#content .forms-skin .fm-btn-success{background:var(--fm-success);color:var(--accent-fg);border-color:var(--fm-success)}
#content .forms-skin .fm-btn-info{background:var(--fm-info);color:var(--accent-fg);border-color:var(--fm-info)}

/* ───────────────────────────── flash banners ───────────────────────────── */
#content .forms-skin .fm-flash{
    border:1px solid transparent;border-radius:var(--radius-lg);
    padding:var(--space-3) var(--space-4);margin-bottom:var(--space-4);font-size:.9rem;line-height:1.45;
}
#content .forms-skin .fm-flash-error{background:color-mix(in srgb,var(--fm-danger) 13%,transparent);border-color:color-mix(in srgb,var(--fm-danger) 32%,transparent);color:var(--fm-danger)}
#content .forms-skin .fm-flash-success{background:color-mix(in srgb,var(--fm-success) 14%,transparent);border-color:color-mix(in srgb,var(--fm-success) 32%,transparent);color:var(--fm-success)}
#content .forms-skin .fm-flash-warning{background:color-mix(in srgb,var(--fm-warning) 16%,transparent);border-color:color-mix(in srgb,var(--fm-warning) 36%,transparent);color:var(--fm-warning)}
#content .forms-skin .fm-flash-info{background:color-mix(in srgb,var(--fm-info) 13%,transparent);border-color:color-mix(in srgb,var(--fm-info) 32%,transparent);color:var(--fm-info)}

/* delete form: sits inline (the actions/detail context owns spacing) */
#content .forms-skin.fm-delete-form{display:inline-block;margin:0}


/* ===================================================================
   modals.css
   =================================================================== */
/* modals.css — the Filament 5 "skin" for the shared SSR modal shell (modals.mix).
 *
 * Plan of record: _plan/2026-06-17-modals-widget.md (§6).
 * Visual target: _doc/forms/modals/ (Filament 5 Modals — ANATOMY only, never its
 * palette: Filament amber → the DCS --accent / --danger / --warning tokens).
 *
 * SCOPING — unlike forms.css/datatable.css (which scope under `#content .X-skin`), this
 * sheet self-scopes on the dialog's own class `.md-modal`. A <dialog> opened with
 * showModal() is a TOP-LAYER element whose ::backdrop may not inherit custom properties,
 * so the --md-* aliases live on `.md-modal` (reading the :root globals, available
 * document-wide) and the ::backdrop uses a LITERAL scrim. This is inherently opt-in:
 * `.md-modal` only exists when a handler calls md_modal(). (Mirrors the datatable's
 * dual-selector + hex-fallback defence for `.dt-modal`.) Inner fm_* fields are skinned by
 * forms.css because the dialog carries `forms-skin` AND stays a #content DOM descendant.
 */

/* ───────────────────────────── tokens ───────────────────────────── */
.md-modal{
    --md-card:   var(--bg-primary, #ffffff);
    --md-text:   var(--fg-primary, #11181c);
    --md-muted:  var(--fg-muted, #5b6b79);
    --md-border: var(--border-muted, #e6e8eb);
    --md-accent: var(--accent, #2f6feb);
    --md-accent-fg: var(--accent-fg, #ffffff);
    --md-danger: var(--danger, #e5484d);
    --md-warning:var(--warning, #d9a000);
    --md-success:var(--success, #30a46c);
    --md-info:   var(--info, #2f6feb);
    --md-r:      var(--radius-xl, 16px);
    --md-rm:     var(--radius-lg, 12px);
}

/* ───────────────────────────── dialog + backdrop ───────────────────────────── */
/* Centered EXPLICITLY (fixed + translate) rather than via the UA dialog margin:auto,
   which is unreliable for a fixed-width / auto-height panel across engines. The open
   animation lives on .md-panel so it never fights this centering transform. */
.md-modal{
    position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);
    margin:0;padding:0;border:0;background:transparent;color:var(--md-text);
    width:min(92vw,32rem);max-width:none;max-height:90vh;overflow:visible;
}
.md-modal::backdrop{ background:var(--overlay); }
@supports (backdrop-filter:blur(2px)){ .md-modal::backdrop{ backdrop-filter:blur(2px); } }

.md-modal .md-panel{
    display:flex;flex-direction:column;max-height:90vh;overflow:hidden;position:relative;
    background:var(--md-card);color:var(--md-text);
    border:1px solid var(--md-border);border-radius:calc(var(--md-r) + 4px);
    box-shadow:var(--shadow-modal);
}
.md-modal .md-form{display:flex;flex-direction:column;min-height:0;max-height:90vh}

/* sizes — explicit WIDTH (content fills) so the panel is a fixed width, not shrink-to-fit */
.md-modal.md-sz-sm{width:min(92vw,22rem)}
.md-modal.md-sz-md{width:min(92vw,32rem)}
.md-modal.md-sz-lg{width:min(93vw,44rem)}
.md-modal.md-sz-xl{width:min(94vw,56rem)}
.md-modal.md-sz-2xl{width:min(95vw,70rem)}

/* ───────────────────────────── header ───────────────────────────── */
.md-modal .md-head{position:relative;padding:var(--space-5) var(--space-5);flex:none}
.md-modal .md-title{margin:0;font-size:1.1rem;font-weight:700;letter-spacing:-.01em;color:var(--md-text)}
.md-modal .md-sub{margin:var(--space-1) 0 0;font-size:.85rem;line-height:1.45;color:var(--md-muted)}
.md-modal .md-head-text{padding-right:var(--space-8)}  /* room for the close X */

.md-modal .md-close{
    position:absolute;top:var(--space-3);right:var(--space-4);display:inline-flex;align-items:center;justify-content:center;
    width:var(--space-8);height:var(--space-8);padding:0;border:0;background:transparent;color:var(--md-muted);
    cursor:pointer;border-radius:var(--radius-full);transition:background .14s ease,color .14s ease;
}
.md-modal .md-close:hover{color:var(--md-text);background:var(--md-border)}
.md-modal .md-close svg{width:var(--space-5);height:var(--space-5);flex:none}

/* confirm header — centered icon-circle + heading + description */
.md-modal.md-confirm .md-head{text-align:center;padding-top:var(--space-7)}
.md-modal .md-icon{
    display:inline-flex;align-items:center;justify-content:center;
    width:3rem;height:3rem;border-radius:var(--radius-full);margin:0 auto var(--space-3);
}
.md-modal .md-icon svg{width:1.5rem;height:1.5rem;flex:none}
.md-modal .md-icon-danger{background:color-mix(in srgb,var(--md-danger) 14%,transparent);color:var(--md-danger)}
.md-modal .md-icon-warning{background:color-mix(in srgb,var(--md-warning) 18%,transparent);color:var(--md-warning)}
.md-modal .md-icon-success{background:color-mix(in srgb,var(--md-success) 16%,transparent);color:var(--md-success)}
.md-modal .md-icon-info{background:color-mix(in srgb,var(--md-info) 14%,transparent);color:var(--md-info)}
.md-modal .md-icon-primary{background:color-mix(in srgb,var(--md-accent) 14%,transparent);color:var(--md-accent)}
.md-modal.md-confirm .md-title{font-size:1.25rem}

/* ───────────────────────────── body ───────────────────────────── */
.md-modal .md-body{padding:0 var(--space-5) var(--space-5);overflow:auto;flex:1 1 auto;min-height:0}
/* stacked fields in a modal body get inter-field spacing (bare fm_* fields, not in an
   fm_grid). A single-field body — e.g. the media upload — is unaffected. */
.md-modal .md-body .fm-field + .fm-field{margin-top:var(--space-4)}
.md-modal.md-confirm .md-body:empty{display:none}
/* a confirm modal's heading/desc live in the header, so its body is usually empty;
   when present, center it to match. */
.md-modal.md-confirm .md-body{text-align:center}

/* ───────────────────────────── footer ───────────────────────────── */
.md-modal .md-foot{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;padding:var(--space-4) var(--space-5);flex:none}
.md-modal .md-foot-split{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3)}
.md-modal .md-foot-split .md-btn{width:100%;padding-top:var(--space-3);padding-bottom:var(--space-3)}

/* sticky variant — header/footer get separator lines, body scrolls between them
   (the flex column already keeps header/footer fixed; this just adds the dividers). */
.md-modal.md-sticky .md-head{border-bottom:1px solid var(--md-border)}
.md-modal.md-sticky .md-foot{border-top:1px solid var(--md-border)}

/* ───────────────────────────── buttons ───────────────────────────── */
.md-modal .md-btn{
    display:inline-flex;align-items:center;justify-content:center;gap:var(--space-1);
    font:inherit;font-size:.9rem;font-weight:600;line-height:1;
    padding:var(--space-2) var(--space-4);border-radius:var(--md-rm);
    border:1px solid transparent;cursor:pointer;white-space:nowrap;text-decoration:none;
    transition:background .14s ease,border-color .14s ease,color .14s ease,filter .14s ease;
}
.md-modal .md-btn svg{width:1.05em;height:1.05em}
.md-modal .md-btn-primary{background:var(--md-accent);color:var(--md-accent-fg);border-color:var(--md-accent)}
.md-modal .md-btn-primary:hover{background:color-mix(in srgb,var(--md-accent) 86%,oklch(0% 0 0));color:var(--md-accent-fg);text-decoration:none}
.md-modal .md-btn-ghost{background:transparent;color:var(--md-text);border-color:var(--md-border)}
.md-modal .md-btn-ghost:hover{background:var(--md-border);color:var(--md-text);text-decoration:none}
.md-modal .md-btn-danger{background:var(--md-danger);color:var(--accent-fg);border-color:var(--md-danger)}
.md-modal .md-btn-danger:hover{filter:brightness(1.06);color:var(--accent-fg);text-decoration:none}
.md-modal .md-btn-warning{background:var(--md-warning);color:var(--accent-fg);border-color:var(--md-warning)}
.md-modal .md-btn-warning:hover{filter:brightness(1.06);color:var(--accent-fg)}
.md-modal .md-btn-success{background:var(--md-success);color:var(--accent-fg);border-color:var(--md-success)}
.md-modal .md-btn-info{background:var(--md-info);color:var(--accent-fg);border-color:var(--md-info)}
.md-modal .md-btn:disabled{opacity:.5;cursor:not-allowed}

/* ───────────────────────────── slide-over (forward-declared) ───────────────────────────── */
/* re-anchor to the right edge, overriding the centered fixed+translate above */
.md-modal.md-slideover{top:0;left:auto;right:0;transform:none;width:min(96vw,30rem);max-height:100vh;height:100vh;margin:0}
.md-modal.md-slideover .md-panel{height:100vh;max-height:100vh;border-radius:0;border-top:0;border-bottom:0;border-right:0}

/* ───────────────────────────── open animation ───────────────────────────── */
/* animate the PANEL (not the dialog) so it never fights the centering transform. */
@media (prefers-reduced-motion:no-preference){
    .md-modal[open] .md-panel{animation:md-in .16s cubic-bezier(.2,.7,.3,1)}
    .md-modal[open]::backdrop{animation:md-fade .16s ease}
    .md-modal.md-slideover[open] .md-panel{animation:md-slide .2s cubic-bezier(.2,.7,.3,1)}
}
@keyframes md-in{from{opacity:0;transform:translateY(10px) scale(.985)}to{opacity:1;transform:none}}
@keyframes md-fade{from{opacity:0}to{opacity:1}}
@keyframes md-slide{from{transform:translateX(100%)}to{transform:none}}


